summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchristian mueller <christian.ei.mueller@bmw.de>2011-12-21 23:58:33 +0100
committerchristian mueller <christian.ei.mueller@bmw.de>2011-12-21 23:58:33 +0100
commitb9b9e9ace5c6c7c493438ecf9a4b33b47543e8e3 (patch)
tree3b5492551a61dd862fb3a042795dd1e59c0cfed6
parentf8a41c140abbd1d193ed19f6c2be598adc01292a (diff)
downloadaudiomanager-b9b9e9ace5c6c7c493438ecf9a4b33b47543e8e3.tar.gz
* first version of SocketHandler working with DBus
* currently Sockethandler test not working
-rw-r--r--AudioManagerDaemon/include/SocketHandler.h137
-rw-r--r--AudioManagerDaemon/src/DBusWrapper.cpp258
-rw-r--r--AudioManagerDaemon/src/SocketHandler.cpp310
-rw-r--r--AudioManagerDaemon/src/main.cpp9
-rw-r--r--AudioManagerDaemon/test/CMakeLists.txt2
-rw-r--r--AudioManagerDaemon/test/sockethandler/sockethandlerTest.cpp38
-rw-r--r--AudioManagerDaemon/test/sockethandler/sockethandlerTest.h12
-rw-r--r--dbusIncludes/DBusWrapper.h35
-rw-r--r--dbusIncludes/SocketHandler.h256
9 files changed, 803 insertions, 254 deletions
diff --git a/AudioManagerDaemon/include/SocketHandler.h b/AudioManagerDaemon/include/SocketHandler.h
deleted file mode 100644
index df6fa7a..0000000
--- a/AudioManagerDaemon/include/SocketHandler.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * 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/DBusWrapper.cpp b/AudioManagerDaemon/src/DBusWrapper.cpp
index 8b84942..0c0ccee 100644
--- a/AudioManagerDaemon/src/DBusWrapper.cpp
+++ b/AudioManagerDaemon/src/DBusWrapper.cpp
@@ -3,7 +3,7 @@
*
* GeniviAudioMananger AudioManagerDaemon
*
-* \file DBusWrapper.cpp
+* \file SocketHandler.cpp
*
* \date 20-Oct-2011 3:42:04 PM
* \author Christian Mueller (christian.ei.mueller@bmw.de)
@@ -23,13 +23,19 @@
*/
#include "DBusWrapper.h"
+#include "SocketHandler.h"
#include <fstream>
#include <sstream>
#include <string>
#include <dlt/dlt.h>
+#include <assert.h>
-DLT_IMPORT_CONTEXT(DLT_CONTEXT)
+#include <iostream> //remove !
+
+using namespace am;
+
+DLT_IMPORT_CONTEXT(DLT_CONTEXT)
#define ROOT_INTROSPECT_XML \
DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \
@@ -43,11 +49,19 @@ DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \
DBusWrapper* DBusWrapper::mReference = NULL;
-DBusWrapper::DBusWrapper()
- : mDbusConnection(0),
+DBusWrapper::DBusWrapper(SocketHandler* socketHandler)
+ : pDbusDispatchCallback(this,&DBusWrapper::dbusDispatchCallback),
+ pDbusFireCallback(this,&DBusWrapper::dbusFireCallback),
+ pDbusCheckCallback(this,&DBusWrapper::dbusCheckCallback),
+ pDbusTimerCallback(this,&DBusWrapper::dbusTimerCallback),
+ mDbusConnection(0),
mDBusError(),
- mNodesList()
+ mNodesList(),
+ mListTimerhandlePointer(),
+ mSocketHandler(socketHandler)
{
+ assert(mSocketHandler!=0);
+ //ok, first lets get the connection
dbus_error_init(&mDBusError);
DLT_LOG(DLT_CONTEXT,DLT_LOG_INFO, DLT_STRING("DBusWrapper::DBusWrapper Opening DBus connection"));
@@ -63,6 +77,19 @@ DBusWrapper::DBusWrapper()
DLT_LOG(DLT_CONTEXT,DLT_LOG_ERROR, DLT_STRING("DBusWrapper::DBusWrapper DBus Connection is null"));
}
+ //then we need to adopt the dbus to our mainloop:
+ //first, we are old enought to live longer then the connection:
+ dbus_connection_set_exit_on_disconnect(mDbusConnection, FALSE);
+
+ //we do not need the manual dispatching, since it is not allowed to call from a different thread. So leave it uncommented:
+ //dbus_connection_set_dispatch_status_function
+
+ //add watch functions:
+ dbus_bool_t ok=dbus_connection_set_watch_functions(mDbusConnection, addWatch, removeWatch, toogleWatch , this, NULL);
+
+ //add timer functions:
+ dbus_bool_t ok2=dbus_connection_set_timeout_functions(mDbusConnection, addTimeout, removeTimeout, toggleTimeout, this, NULL);
+
mObjectPathVTable.message_function=DBusWrapper::cbRootIntrospection;
dbus_connection_register_object_path(mDbusConnection,DBUS_SERVICE_OBJECT_PATH , &mObjectPathVTable, this);
int ret = dbus_bus_request_name(mDbusConnection,DBUS_SERVICE_PREFIX,DBUS_NAME_FLAG_DO_NOT_QUEUE, &mDBusError);
@@ -75,6 +102,15 @@ DBusWrapper::DBusWrapper()
{
DLT_LOG(DLT_CONTEXT,DLT_LOG_ERROR, DLT_STRING("DBusWrapper::DBusWrapper Wrapper is not the Primary Owner"), DLT_INT(ret));
}
+// dbus_connection_ref(mDbusConnection);
+// DBusDispatchStatus dstatus;
+// do
+// {
+// dstatus=dbus_connection_dispatch(mDbusConnection);
+// std::cout<<"status"<<dstatus<<std::endl;
+// }
+// while (dstatus!=DBUS_DISPATCH_COMPLETE);
+// dbus_connection_unref(mDbusConnection);
}
DBusWrapper::~DBusWrapper()
@@ -82,6 +118,13 @@ DBusWrapper::~DBusWrapper()
//close the connection again
DLT_LOG(DLT_CONTEXT,DLT_LOG_INFO, DLT_STRING("DBusWrapper::~DBusWrapper Closing DBus connection"));
dbus_connection_unref(mDbusConnection);
+
+ //clean up all timerhandles we created but did not delete before
+ std::vector<sh_timerHandle_t*>::iterator it=mListTimerhandlePointer.begin();
+ for(;it!=mListTimerhandlePointer.end();++it)
+ {
+ delete *it;
+ }
}
void DBusWrapper::registerCallback(const DBusObjectPathVTable* vtable, const std::string& path, void* userdata)
@@ -164,9 +207,214 @@ void DBusWrapper::getDBusConnection(DBusConnection *& connection) const
connection=mDbusConnection;
}
+dbus_bool_t DBusWrapper::addWatch(DBusWatch *watch, void *userData)
+{
+ mReference=(DBusWrapper*)userData;
+ assert(mReference!=0);
+ return mReference->addWatchDelegate(watch,userData);
+}
+
+dbus_bool_t DBusWrapper::addWatchDelegate(DBusWatch * watch, void* userData)
+{
+ short event=0;
+ uint flags=dbus_watch_get_flags(watch);
+ /* no watch flags for disabled watches */
+ if (dbus_watch_get_enabled(watch))
+ {
+ if (flags & DBUS_WATCH_READABLE) event |= POLLIN;
+ if (flags & DBUS_WATCH_WRITABLE) event |= POLLOUT;
+ }
+
+ sh_pollHandle_t handle=0;
+ am_Error_e error=mSocketHandler->addFDPoll(dbus_watch_get_unix_fd(watch),event,NULL,&pDbusFireCallback,&pDbusCheckCallback,&pDbusDispatchCallback,watch,handle);
+
+ //if everything is alright, add the watch and the handle to our map so we know this relationship
+ if (error==E_OK && handle!=0)
+ {
+ mMapHandleWatch.insert(std::make_pair(watch,handle));
+ return true;
+ }
+ return false;
+}
+
+void DBusWrapper::removeWatch(DBusWatch *watch, void *userData)
+{
+ mReference=(DBusWrapper*)userData;
+ assert(mReference!=0);
+ mReference->removeWatchDelegate(watch,userData);
+}
+
+void DBusWrapper::removeWatchDelegate(DBusWatch *watch, void *userData)
+{
+ std::map<DBusWatch*,sh_pollHandle_t>::iterator iterator=mMapHandleWatch.begin();
+ iterator=mMapHandleWatch.find(watch);
+ if (iterator!=mMapHandleWatch.end()) mSocketHandler->removeFDPoll(iterator->second);
+ mMapHandleWatch.erase(iterator);
+}
+
+void DBusWrapper::toogleWatch(DBusWatch *watch, void *userData)
+{
+ mReference=(DBusWrapper*)userData;
+ assert(mReference!=0);
+ mReference->toogleWatchDelegate(watch,userData);
+}
+
+void DBusWrapper::toogleWatchDelegate(DBusWatch *watch, void *userData)
+{
+ short event=0;
+ int watchFD=dbus_watch_get_unix_fd(watch);
+ uint flags=dbus_watch_get_flags(watch);
+ /* no watch flags for disabled watches */
+ if (dbus_watch_get_enabled(watch))
+ {
+ if (flags & DBUS_WATCH_READABLE) event |= POLLIN;
+ if (flags & DBUS_WATCH_WRITABLE) event |= POLLOUT;
+ }
+ std::map<DBusWatch*,sh_pollHandle_t>::iterator iterator=mMapHandleWatch.begin();
+ iterator=mMapHandleWatch.find(watch);
+ if (iterator!=mMapHandleWatch.end()) mSocketHandler->updateEventFlags(iterator->second,event);
+}
+
+dbus_bool_t DBusWrapper::addTimeout(DBusTimeout *timeout, void* userData)
+{
+ mReference=(DBusWrapper*)userData;
+ assert(mReference!=0);
+ return mReference->addTimeoutDelegate(timeout,userData);
+}
+
+dbus_bool_t DBusWrapper::addTimeoutDelegate(DBusTimeout *timeout,void* userData)
+{
+ if (!dbus_timeout_get_enabled(timeout)) return false;
+
+ //calculate the timeout in timeval
+ timespec pollTimeout;
+ int localTimeout=dbus_timeout_get_interval(timeout);
+ pollTimeout.tv_sec=localTimeout/1000;
+ pollTimeout.tv_nsec=(localTimeout%1000)*1000000;
+
+ //prepare handle and callback. new is eval, but there is no other choice because we need the pointer!
+ sh_timerHandle_t* handle=new sh_timerHandle_t;
+ mListTimerhandlePointer.push_back(handle);
+ TBasicTimerCallback* buffer=&pDbusTimerCallback;
+
+ //add the timer to the pollLoop
+ mSocketHandler->addTimer(pollTimeout,buffer,*handle,timeout);
+
+ //save the handle with dbus context
+ dbus_timeout_set_data(timeout, handle, NULL);
+
+ //save timeout in Socket context
+ userData=timeout;
+ return true;
+}
+
+void DBusWrapper::removeTimeout(DBusTimeout *timeout, void* userData)
+{
+ mReference=(DBusWrapper*)userData;
+ assert(mReference!=0);
+ mReference->removeTimeoutDelegate(timeout,userData);
+}
+
+void DBusWrapper::removeTimeoutDelegate(DBusTimeout *timeout, void* userData)
+{
+ //get the pointer to the handle and remove the timer
+ sh_timerHandle_t* handle=(sh_timerHandle_t*)dbus_timeout_get_data(timeout);
+ mSocketHandler->removeTimer(*handle);
+
+ //now go throught the timerlist and remove the pointer, free memory
+ std::vector<sh_timerHandle_t*>::iterator it=mListTimerhandlePointer.begin();
+ for(;it!=mListTimerhandlePointer.end();++it)
+ {
+ if (*it==handle)
+ {
+ mListTimerhandlePointer.erase(it);
+ break;
+ }
+ }
+ delete handle;
+}
+
+void DBusWrapper::toggleTimeout(DBusTimeout *timeout, void* userData)
+{
+ mReference=(DBusWrapper*)userData;
+ assert(mReference!=0);
+ mReference->toggleTimeoutDelegate(timeout,userData);
+}
+
+bool am::DBusWrapper::dbusDispatchCallback(const sh_pollHandle_t handle, void *userData)
+{
+ bool returnVal=false;
+ dbus_connection_ref(mDbusConnection);
+ if (dbus_connection_dispatch(mDbusConnection)==DBUS_DISPATCH_COMPLETE) returnVal=true;
+ dbus_connection_unref(mDbusConnection);
+ return returnVal;
+}
+
+bool am::DBusWrapper::dbusCheckCallback(const sh_pollHandle_t handle, void *userData)
+{
+ bool returnVal=false;
+ dbus_connection_ref(mDbusConnection);
+ if (dbus_connection_get_dispatch_status(mDbusConnection) == DBUS_DISPATCH_DATA_REMAINS) returnVal=true;
+ dbus_connection_unref(mDbusConnection);
+ return returnVal;
+}
+
+void am::DBusWrapper::dbusFireCallback(const pollfd pollfd, const sh_pollHandle_t handle, void *userData)
+{
+ assert(userData!=NULL);
+ uint flags=0;
+
+ if (!dbus_watch_get_enabled((DBusWatch*)userData))
+ {
+ std::cout<<"sdfsdf"<<std::endl;
+ }
+
+ if (pollfd.revents & POLLIN) flags |= DBUS_WATCH_READABLE;
+ if (pollfd.revents & POLLOUT) flags |= DBUS_WATCH_WRITABLE;
+ if (pollfd.revents & POLLHUP) flags |= DBUS_WATCH_HANGUP;
+ if (pollfd.revents & POLLERR) flags |= DBUS_WATCH_ERROR;
+
+// std::cout<<fd<<" "<<revent<<std::endl;
+ DBusWatch *watch=(DBusWatch*)userData;
+
+ dbus_connection_ref(mDbusConnection);
+ bool ok=dbus_watch_handle(watch, flags);
+ dbus_connection_unref(mDbusConnection);
+}
+void DBusWrapper::toggleTimeoutDelegate(DBusTimeout *timeout, void* userData)
+{
+ //get the pointer to the handle and remove the timer
+ sh_timerHandle_t* handle=(sh_timerHandle_t*)dbus_timeout_get_data(timeout);
+ //stop or restart?
+ if (dbus_timeout_get_enabled(timeout))
+ {
+ //calculate the timeout in timeval
+ timespec pollTimeout;
+ int localTimeout=dbus_timeout_get_interval(timeout);
+ pollTimeout.tv_sec=localTimeout/1000;
+ pollTimeout.tv_nsec=(localTimeout%1000)*1000000;
+ mSocketHandler->restartTimer(*handle,pollTimeout);
+ }
+ else
+ {
+ mSocketHandler->stopTimer(*handle);
+ }
+}
+void DBusWrapper::dbusTimerCallback(sh_timerHandle_t handle, void *userData)
+{
+ assert(userData!=NULL);
+ if (dbus_timeout_get_enabled((DBusTimeout*)userData))
+ {
+ timespec ts;
+ ts.tv_nsec=-1;
+ ts.tv_sec=-1;
+ mSocketHandler->restartTimer(handle,ts);
+ }
+ dbus_timeout_handle((DBusTimeout*)userData);
+}
diff --git a/AudioManagerDaemon/src/SocketHandler.cpp b/AudioManagerDaemon/src/SocketHandler.cpp
index eecba5a..5a0de5e 100644
--- a/AudioManagerDaemon/src/SocketHandler.cpp
+++ b/AudioManagerDaemon/src/SocketHandler.cpp
@@ -1,9 +1,26 @@
-/*
- * SocketHandler.cpp
- *
- * Created on: Dec 18, 2011
- * Author: christian
- */
+/**
+* Copyright (C) 2011, BMW AG
+*
+* GeniviAudioMananger AudioManagerDaemon
+*
+* \file DBusWrapper.cpp
+*
+* \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.
+*
+*/
#include "SocketHandler.h"
#include <assert.h>
@@ -21,12 +38,13 @@
namespace am {
SocketHandler::SocketHandler()
- :mMapFdCallback(),
+ :mListPoll(),
mListTimer(),
- mListPollfd(),
+ mListActiveTimer(),
mNextTimer(),
- mLastInsertedHandle(1),
- mDispatch(true)
+ mLastInsertedHandle(0),
+ mDispatch(true),
+ mRecreatePollfds(true)
{
mTimeout.tv_nsec=-1;
mTimeout.tv_sec=-1;
@@ -43,15 +61,31 @@ SocketHandler::~SocketHandler()
*/
void SocketHandler::start_listenting()
{
- int pollStatus;
+ int16_t pollStatus;
+ std::list<int16_t>hitList;
//init the timer
initTimer();
while (mDispatch)
{
+ //first we go through the registered filedescriptors and check if someone needs preparation:
+ mListPoll_t::iterator prepIter=mListPoll.begin();
+ shPollPrepare *prep=NULL;
+ for(;prepIter!=mListPoll.end();++prepIter)
+ {
+ if((prep=prepIter->prepareCB)!=NULL) prep->Call(prepIter->handle,prepIter->userData);
+ }
+
+ if(mRecreatePollfds)
+ {
+ //there was a change in the setup, so we need to recreate the fdarray from the list
+ std::for_each(mListPoll.begin(),mListPoll.end(),CopyPollfd(mfdPollingArray));
+ mRecreatePollfds=false;
+ }
+
//block until something is on a filedescriptor
- if((pollStatus=poll(&mListPollfd.front(),mListPollfd.size(),timespec2ms(mTimeout)))==-1)
+ if((pollStatus=poll(&mfdPollingArray.front(),mfdPollingArray.size(),timespec2ms(mTimeout)))==-1)
{
//todo enter DLT message here;
}
@@ -60,23 +94,59 @@ void SocketHandler::start_listenting()
{
//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();
+ //first, we check what happened:
+ mPollfd_t::iterator iterator=mfdPollingArray.begin();
+ mPollfd_t::iterator iteratorEnd=mfdPollingArray.end();
for(;iterator!=iteratorEnd;++iterator)
{
- //oh yes! then, fire the callback !
- if(iterator->revents !=0)
+ //get all indexes of the fired events and save them int hitList
+ hitList.clear();
+ std::vector<pollfd>::iterator it=mfdPollingArray.begin();
+ do
{
- //check the map for the right callback
- mMapFdCallback_t::iterator iteratorCB=mMapFdCallback.begin();
- iteratorCB=mMapFdCallback.find(iterator->fd);
- if(iteratorCB!=mMapFdCallback.end())
+ it=std::find_if(it,mfdPollingArray.end(),onlyFiredEvents);
+ if (it!=mfdPollingArray.end()) hitList.push_back(std::distance(mfdPollingArray.begin(), it++));
+
+ } while (it!=mfdPollingArray.end());
+
+ //stage 1, call firedCB for all matched events, but only if callback is not zero!
+ std::list<int16_t>::iterator hListIt=hitList.begin();
+ for(;hListIt!=hitList.end();++hListIt)
+ {
+ shPollFired* fire=NULL;
+ if ((fire=mListPoll.at(*hListIt).firedCB)!=NULL) fire->Call(mfdPollingArray.at(*hListIt),mListPoll.at(*hListIt).handle,mListPoll.at(*hListIt).userData);
+ }
+
+ //stage 2, lets ask around if some dispatching is necessary, if not, they are taken from the hitlist
+ hListIt=hitList.begin();
+ for(;hListIt!=hitList.end();++hListIt)
+ {
+ shPollCheck* check=NULL;
+ if ((check=mListPoll.at(*hListIt).checkCB)!=NULL)
{
- //fire!
- iteratorCB->second->Call(iterator->fd,iterator->events);
+ if (!check->Call(mListPoll.at(*hListIt).handle,mListPoll.at(*hListIt).userData))
+ {
+ hListIt=hitList.erase(hListIt);
+ }
}
}
+
+ //stage 3, the ones left need to dispatch, we do this as long as there is something to dispatch..
+ do
+ {
+ hListIt=hitList.begin();
+ for(;hListIt!=hitList.end();++hListIt)
+ {
+ shPollDispatch *dispatch=NULL;
+ if((dispatch=mListPoll.at(*hListIt).dispatchCB)!=NULL)
+ {
+ if (dispatch->Call(mListPoll.at(*hListIt).handle,mListPoll.at(*hListIt).userData))
+ {
+ hListIt=hitList.erase(hListIt);
+ }
+ }
+ }
+ } while (!hitList.empty());
}
}
else //Timerevent
@@ -102,20 +172,27 @@ void SocketHandler::stop_listening()
* @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)
+am_Error_e SocketHandler::addFDPoll(const int fd,const short event, shPollPrepare *prepare,shPollFired *fired,shPollCheck *check,shPollDispatch *dispatch, void* userData,sh_pollHandle_t& handle)
{
if (!fdIsValid(fd)) return E_NON_EXISTENT;
- pollfd tempPollfd;
- tempPollfd.fd=fd;
- tempPollfd.events=event;
- tempPollfd.revents=NULL;
+ sh_poll_s pollData;
+ pollData.handle=++mLastInsertedPollHandle;
+ pollData.pollfdValue.fd=fd;
+ pollData.pollfdValue.events=event;
+ pollData.pollfdValue.revents=0;
+ pollData.userData=userData;
+ pollData.prepareCB=prepare;
+ pollData.firedCB=fired;
+ pollData.checkCB=check;
+ pollData.dispatchCB=dispatch;
+
+ //add new data to the list
+ mListPoll.push_back(pollData);
- //insert the filedescriptor into the poll array
- mListPollfd.push_back(tempPollfd);
+ mRecreatePollfds=true;
- //insert the callback into the map
- mMapFdCallback.insert(std::make_pair(fd,callback));
+ handle=pollData.handle;
return E_OK;
}
@@ -124,24 +201,16 @@ am_Error_e SocketHandler::addFDPoll(const int fd, const short event, TBasicPollC
* @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)
+am_Error_e SocketHandler::removeFDPoll(const sh_pollHandle_t handle)
{
- mMapFdCallback_t::iterator iterator=mMapFdCallback.begin();
+ mListPoll_t::iterator iterator=mListPoll.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)
+ for (;iterator!=mListPoll.end();++iterator)
{
- if (pollIterator->fd==fd)
+ if(iterator->handle==handle)
{
- mListPollfd.erase(pollIterator);
+ iterator=mListPoll.erase(iterator);
+ mRecreatePollfds=true;
return E_OK;
}
}
@@ -158,7 +227,7 @@ am_Error_e SocketHandler::removeFDPoll(const int fd)
* @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)
+am_Error_e SocketHandler::addTimer(const timespec timeouts,TBasicTimerCallback*& callback,sh_timerHandle_t& handle, void * userData)
{
assert(!((timeouts.tv_sec==0) && (timeouts.tv_nsec==0)));
assert(callback!=NULL);
@@ -166,18 +235,20 @@ am_Error_e SocketHandler::addTimer(const timespec timeouts,TBasicTimerCallback*&
timer_s timerItem;
//create a new handle for the timer
- handle=mLastInsertedHandle++; //todo: overflow ruling !
+ handle=++mLastInsertedHandle; //todo: overflow ruling !
timerItem.handle=handle;
timerItem.countdown=timeouts;
timerItem.timeout=timeouts;
timerItem.callback=callback;
+ timerItem.userData=userData;
//add timer to the list
+ mListActiveTimer.push_back(timerItem);
mListTimer.push_back(timerItem);
//very important: sort the list so that the smallest value is front
- mListTimer.sort(compareCountdown);
- mTimeout=mListTimer.front().countdown;
+ mListActiveTimer.sort(compareCountdown);
+ mTimeout=mListActiveTimer.front().countdown;
return E_OK;
}
@@ -186,20 +257,69 @@ am_Error_e SocketHandler::addTimer(const timespec timeouts,TBasicTimerCallback*&
* @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)
+am_Error_e SocketHandler::removeTimer(const sh_timerHandle_t handle)
{
assert(handle!=0);
- //go through the list and remove the timer with the handle
+ //stop the current timer
+ stopTimer(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())
+ return E_OK;
+ }
+ }
+ return E_UNKNOWN;
+}
+
+/**
+ * restarts a timer and updates with a new interval
+ * @param handle handle to the timer
+ * @param timeouts new timout time
+ * @return E_OK on success, E_NON_EXISTENT if the handle was not found
+ */
+am_Error_e SocketHandler::restartTimer(const sh_timerHandle_t handle, const timespec timeouts)
+{
+ timer_s timerItem;
+ std::list<timer_s>::iterator it=mListTimer.begin();
+ for(;it!=mListTimer.end();++it)
+ {
+ if (it->handle==handle)
+ {
+ timerItem=*it;
+ break;
+ }
+ }
+
+ if (timeouts.tv_nsec!=-1 && timeouts.tv_sec!=-1)
+ {
+ timerItem.timeout=timeouts;
+ }
+
+ mListActiveTimer.push_back(timerItem);
+
+ //very important: sort the list so that the smallest value is front
+ mListActiveTimer.sort(compareCountdown);
+ mTimeout=mListActiveTimer.front().countdown;
+ return E_OK;
+}
+
+am_Error_e SocketHandler::stopTimer(const sh_timerHandle_t handle)
+{
+ //go through the list and remove the timer with the handle
+ std::list<timer_s>::iterator it=mListActiveTimer.begin();
+ for(;it!=mListActiveTimer.end();++it)
+ {
+ if(it->handle==handle)
+ {
+ it=mListActiveTimer.erase(it);
+ if (!mListActiveTimer.empty())
{
- mTimeout=mListTimer.front().countdown;
+ mTimeout=mListActiveTimer.front().countdown;
}
else
{
@@ -209,6 +329,28 @@ am_Error_e SocketHandler::removeTimer(const timerHandle_t handle)
return E_OK;
}
}
+ return E_NON_EXISTENT;
+}
+
+/**
+ * updates the eventFlags of a poll
+ * @param fd the filedescriptor of the poll
+ * @param event the event flags
+ * @return E_OK on succsess, E_NON_EXISTENT if fd was not found
+ */
+am_Error_e SocketHandler::updateEventFlags(const sh_pollHandle_t handle, const short events)
+{
+ mListPoll_t::iterator iterator=mListPoll.begin();
+
+ for (;iterator!=mListPoll.end();++iterator)
+ {
+ if(iterator->handle==handle)
+ {
+ iterator->pollfdValue.events=events;
+ mRecreatePollfds=true;
+ return E_OK;
+ }
+ }
return E_UNKNOWN;
}
@@ -229,15 +371,15 @@ bool SocketHandler::fdIsValid(const int fd) const
void SocketHandler::timerUp()
{
//first fire the event
- mListTimer.front().callback->Call(mListTimer.front().handle);
+ mListActiveTimer.front().callback->Call(mListActiveTimer.front().handle,mListActiveTimer.front().userData);
//then remove the first timer, the one who fired
- mListTimer.pop_front();
- if(!mListTimer.empty())
+ mListActiveTimer.pop_front();
+ if(!mListActiveTimer.empty())
{
//substract the old value from all timers in the list
- std::for_each(mListTimer.begin(),mListTimer.end(),SubstractTime(mTimeout));
- mTimeout=mListTimer.front().countdown;
+ std::for_each(mListActiveTimer.begin(),mListActiveTimer.end(),SubstractTime(mTimeout));
+ mTimeout=mListActiveTimer.front().countdown;
}
else
{
@@ -247,13 +389,13 @@ void SocketHandler::timerUp()
}
/**
- * inits the timers
+ * init the timers
*/
void SocketHandler::initTimer()
{
- if(!mListTimer.empty())
+ if(!mListActiveTimer.empty())
{
- mTimeout=mListTimer.front().countdown;
+ mTimeout=mListActiveTimer.front().countdown;
}
else
{
@@ -262,34 +404,38 @@ void SocketHandler::initTimer()
}
}
+
/**
- * convert timespec to milliseconds
- * @param time time in timespec
- * @return time in milliseconds
- */
-inline int SocketHandler::timespec2ms(const timespec& time)
+* 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;
+ 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
+* 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;
+ 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;
}
- else
- {
- t.countdown.tv_nsec=val;
- }
- (t.countdown.tv_sec-param.tv_sec)<0 ? 0 : (t.countdown.tv_sec-=param.tv_sec);
+ (t.countdown.tv_sec - param.tv_sec) < 0 ? 0 : (t.countdown.tv_sec -= param.tv_sec);
}
+void SocketHandler::CopyPollfd::operator ()(const sh_poll_s & row)
+{
+ mArray.push_back(row.pollfdValue);
+}
+
+/* namespace am */
+}
-} /* namespace am */
diff --git a/AudioManagerDaemon/src/main.cpp b/AudioManagerDaemon/src/main.cpp
index 34a0fc1..7da8f2d 100644
--- a/AudioManagerDaemon/src/main.cpp
+++ b/AudioManagerDaemon/src/main.cpp
@@ -34,6 +34,7 @@
//todo: check the startup sequence. Dbus shall be activated last...
//todo: there is a bug in the visible flags of sinks and sources. fix it.
//todo: check namespace handling. no use.. in headers
+//todo: make sure that iterators have a fixed end to prevent crashed while adding vectors while iterating on critical vectors
#include "DatabaseHandler.h"
#include "DatabaseObserver.h"
@@ -44,6 +45,7 @@
#include "CommandSender.h"
#include "RoutingSender.h"
#include "DBusWrapper.h"
+#include "SocketHandler.h"
#include <dbus/dbus.h>
#include <dlt/dlt.h>
@@ -70,7 +72,8 @@ int main(int argc, char *argv[])
//Instantiate all classes. Keep in same order !
DatabaseHandler iDatabaseHandler(std::string(":memory:"));
- DBusWrapper iDBusWrapper;
+ SocketHandler iSocketHandler;
+ DBusWrapper iDBusWrapper(&iSocketHandler);
RoutingSender iRoutingSender(listRoutingPluginDirs);
CommandSender iCommandSender(listCommandPluginDirs);
ControlSender iControlSender(std::string(CONTROLLER_PLUGIN));
@@ -86,8 +89,8 @@ int main(int argc, char *argv[])
iCommandSender.startupInterface(&iCommandReceiver);
iRoutingSender.startupRoutingInterface(&iRoutingReceiver);
-
- iDBusWrapper.dbusMainLoop();
+ iSocketHandler.start_listenting();
+ //iDBusWrapper.dbusMainLoop();
}
diff --git a/AudioManagerDaemon/test/CMakeLists.txt b/AudioManagerDaemon/test/CMakeLists.txt
index e2e22c0..3ee415a 100644
--- a/AudioManagerDaemon/test/CMakeLists.txt
+++ b/AudioManagerDaemon/test/CMakeLists.txt
@@ -15,4 +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
+#add_subdirectory (sockethandler) \ No newline at end of file
diff --git a/AudioManagerDaemon/test/sockethandler/sockethandlerTest.cpp b/AudioManagerDaemon/test/sockethandler/sockethandlerTest.cpp
index 2cab649..c9c17cb 100644
--- a/AudioManagerDaemon/test/sockethandler/sockethandlerTest.cpp
+++ b/AudioManagerDaemon/test/sockethandler/sockethandlerTest.cpp
@@ -25,7 +25,7 @@ sockethandlerTest::~sockethandlerTest()
{
}
-void fdCallBack::connectSocket(int fd, const short events)
+void fdCallBack::connectSocket(int fd, const short events,void * userData)
{
std::cout<<"Socket connection received and open"<<std::endl;
@@ -34,9 +34,9 @@ void fdCallBack::connectSocket(int fd, const short events)
short event = 0;
event |=POLLIN;
- TBasicPollCallback* buf=&pSocketDataCallback;
+ shPollCallBack* buf=&pSocketDataCallback;
//add new socketConnection to the handler
- mSocketHandler->addFDPoll(mSocketConnection,event,buf);
+ mSocketHandler->addFDPoll(mSocketConnection,event,buf,NULL);
}
@@ -52,7 +52,7 @@ fdCallBack::fdCallBack(SocketHandler *SocketHandler)
-void am::fdCallBack::handleSocketData(int fd, const short events)
+void am::fdCallBack::handleSocketData(int fd, const short events, void* userdata)
{
char buffer[3000];
std::string msg;
@@ -93,36 +93,36 @@ am::timerCallBack::~timerCallBack()
-void am::timerCallBack::timer1Callback(SocketHandler::timerHandle_t handle)
+void am::timerCallBack::timer1Callback(SocketHandler::sh_timerHandle_t handle, void* userData)
{
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_);
+ SocketHandler::sh_timerHandle_t handle_;
+ mSocketHandler->addTimer(timeout,buf,handle_,NULL);
}
-void am::timerCallBack::timer2Callback(SocketHandler::timerHandle_t handle)
+void am::timerCallBack::timer2Callback(SocketHandler::sh_timerHandle_t handle, void* userData)
{
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_);
+ SocketHandler::sh_timerHandle_t handle_;
+ mSocketHandler->addTimer(timeout,buf,handle_,NULL);
}
-void am::timerCallBack::timer3Callback(SocketHandler::timerHandle_t handle)
+void am::timerCallBack::timer3Callback(SocketHandler::sh_timerHandle_t handle, void* userData)
{
std::cout<<"callback3 called"<<std::endl;
}
-void am::timerCallBack::timer4Callback(SocketHandler::timerHandle_t handle)
+void am::timerCallBack::timer4Callback(SocketHandler::sh_timerHandle_t handle, void* userData)
{
std::cout<<"callback4 called"<<std::endl;
}
@@ -151,9 +151,9 @@ void* playWithSocketServer(void* data)
short event = 0;
event |=POLLIN;
- TBasicPollCallback* buf=&testCallback.pSocketConnectionCallback;
+ shPollCallBack* buf=&testCallback.pSocketConnectionCallback;
//add the callback to the Sockethandler
- myHandler.addFDPoll(socketHandle, event, buf);
+ myHandler.addFDPoll(socketHandle, event, buf, NULL);
//start the mainloop
myHandler.start_listenting();
@@ -216,11 +216,11 @@ TEST(sockethandlerTest,playWithTimers)
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);
+ SocketHandler::sh_timerHandle_t handle;
+ myHandler.addTimer(timeoutTime,buf,handle,NULL);
+ myHandler.addTimer(timeout2,buf2,handle,NULL);
+ myHandler.addTimer(timeout3,buf3,handle,NULL);
+ myHandler.addTimer(timeout4,buf4,handle,NULL);
myHandler.start_listenting();
}
diff --git a/AudioManagerDaemon/test/sockethandler/sockethandlerTest.h b/AudioManagerDaemon/test/sockethandler/sockethandlerTest.h
index 5b86ad9..81ded2a 100644
--- a/AudioManagerDaemon/test/sockethandler/sockethandlerTest.h
+++ b/AudioManagerDaemon/test/sockethandler/sockethandlerTest.h
@@ -18,8 +18,8 @@ class fdCallBack
public:
fdCallBack(SocketHandler *SocketHandler);
virtual ~fdCallBack();
- void connectSocket(int fd,const short events);
- void handleSocketData(int fd,const short events);
+ void connectSocket(int fd,const short events,void * userData);
+ void handleSocketData(int fd,const short events,void * userData);
TSpecificPollCallback<fdCallBack> pSocketDataCallback;
TSpecificPollCallback<fdCallBack> pSocketConnectionCallback;
private:
@@ -32,10 +32,10 @@ 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);
+ void timer1Callback(SocketHandler::sh_timerHandle_t handle,void * userData);
+ void timer2Callback(SocketHandler::sh_timerHandle_t handle,void * userData);
+ void timer3Callback(SocketHandler::sh_timerHandle_t handle,void * userData);
+ void timer4Callback(SocketHandler::sh_timerHandle_t handle,void * userData);
TSpecificTimerCallback<timerCallBack> pTimer1Callback;
TSpecificTimerCallback<timerCallBack> pTimer2Callback;
TSpecificTimerCallback<timerCallBack> pTimer3Callback;
diff --git a/dbusIncludes/DBusWrapper.h b/dbusIncludes/DBusWrapper.h
index 12bbb9a..42190a5 100644
--- a/dbusIncludes/DBusWrapper.h
+++ b/dbusIncludes/DBusWrapper.h
@@ -28,16 +28,18 @@
#include "DBusConfiguration.h"
+#include "SocketHandler.h"
#include <dbus/dbus.h>
#include <string>
#include <list>
+namespace am {
/**
* This wraps dbus and provides everything needed to anyone who wants to use dbus (including plugins)
*/
class DBusWrapper {
public:
- DBusWrapper();
+ DBusWrapper(SocketHandler* socketHandler);
virtual ~DBusWrapper();
/**
@@ -60,13 +62,44 @@ public:
*/
void dbusMainLoop();
+ static dbus_bool_t addWatch(DBusWatch *watch, void *userData);
+ static void removeWatch(DBusWatch *watch, void *userData);
+ static void toogleWatch(DBusWatch *watch, void *userData);
+
+ static dbus_bool_t addTimeout(DBusTimeout *timeout,void* userData);
+ static void removeTimeout(DBusTimeout *timeout, void* userData);
+ static void toggleTimeout(DBusTimeout *timeout, void* userData);
+
+ bool dbusDispatchCallback(const sh_pollHandle_t handle, void* userData);
+ shPollDispatch_T<DBusWrapper> pDbusDispatchCallback;
+
+ bool dbusCheckCallback(const sh_pollHandle_t handle, void* userData);
+ shPollCheck_T<DBusWrapper> pDbusCheckCallback;
+
+ void dbusFireCallback(const pollfd pollfd,const sh_pollHandle_t handle, void* userData);
+ shPollFired_T<DBusWrapper> pDbusFireCallback;
+
+ void dbusTimerCallback(sh_timerHandle_t handle, void* userData);
+ TSpecificTimerCallback<DBusWrapper> pDbusTimerCallback;
+
private:
static DBusWrapper* mReference;
static DBusHandlerResult cbRootIntrospection(DBusConnection *conn, DBusMessage *msg, void *reference);
+ dbus_bool_t addWatchDelegate(DBusWatch * watch,void* userData);
+ void removeWatchDelegate(DBusWatch *watch, void *userData);
+ void toogleWatchDelegate(DBusWatch *watch, void *userData);
+ dbus_bool_t addTimeoutDelegate(DBusTimeout *timeout,void* userData);
+ void removeTimeoutDelegate(DBusTimeout *timeout, void* userData);
+ void toggleTimeoutDelegate(DBusTimeout *timeout, void* userData);
DBusObjectPathVTable mObjectPathVTable;
DBusConnection* mDbusConnection;
DBusError mDBusError;
std::list<std::string> mNodesList;
+ std::vector<sh_timerHandle_t*> mListTimerhandlePointer;
+ SocketHandler *mSocketHandler;
+ std::map<DBusWatch*,sh_pollHandle_t> mMapHandleWatch;
};
+}
+
#endif /* DBUSWRAPPER_H_ */
diff --git a/dbusIncludes/SocketHandler.h b/dbusIncludes/SocketHandler.h
new file mode 100644
index 0000000..c76e343
--- /dev/null
+++ b/dbusIncludes/SocketHandler.h
@@ -0,0 +1,256 @@
+/**
+* Copyright (C) 2011, BMW AG
+*
+* GeniviAudioMananger AudioManagerDaemon
+*
+* \file SocketHandler.h
+*
+* \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.
+*
+*/
+
+#ifndef SOCKETHANDLER_H_
+#define SOCKETHANDLER_H_
+
+#include <audiomanagertypes.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <stdint.h>
+#include <sys/poll.h>
+#include <list>
+#include <map>
+
+namespace am {
+
+typedef uint16_t sh_timerHandle_t; //!<this is a handle for a timer to be used with the SocketHandler
+typedef uint16_t sh_pollHandle_t; //!<this is a handle for a filedescriptor to be used with the SocketHandler
+
+class shPollPrepare;
+class shPollCheck;
+class shPollFired;
+class shPollDispatch;
+class TBasicTimerCallback;
+
+class SocketHandler
+{
+public:
+ SocketHandler();
+ virtual ~SocketHandler();
+
+ am_Error_e addFDPoll(const int fd,const short event, shPollPrepare *prepare,shPollFired *fired,shPollCheck *check,shPollDispatch *dispatch, void* userData,sh_pollHandle_t& handle);
+ am_Error_e removeFDPoll(const sh_pollHandle_t handle);
+ am_Error_e updateEventFlags(const sh_pollHandle_t handle, const short events);
+ am_Error_e addTimer(const timespec timeouts,TBasicTimerCallback*& callback,sh_timerHandle_t& handle, void* userData);
+ am_Error_e removeTimer(const sh_timerHandle_t handle);
+ am_Error_e restartTimer(const sh_timerHandle_t handle, const timespec timeouts);
+ am_Error_e stopTimer(const sh_timerHandle_t handle);
+ void start_listenting();
+ void stop_listening();
+
+private:
+ struct timer_s //!<struct that holds information of timers
+ {
+ sh_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
+ void * userData; //!<saves a void pointer together with the rest.
+ };
+
+ 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;
+ };
+
+ struct sh_poll_s //!<struct that holds information about polls
+ {
+ sh_pollHandle_t handle; //!<handle to uniquely adress a filedesriptor
+ shPollPrepare *prepareCB;
+ shPollFired *firedCB;
+ shPollCheck *checkCB;
+ shPollDispatch *dispatchCB;
+ pollfd pollfdValue; //!<the array for polling the filedescriptors
+ void *userData; //!<userdata saved together with the callback.
+ };
+
+ typedef std::vector<pollfd> mPollfd_t; //!<vector of filedescriptors
+ typedef std::vector<sh_poll_s> mListPoll_t; //!<list for the callbacks
+
+ class CopyPollfd
+ {
+ private:
+ mPollfd_t& mArray;
+ public:
+ CopyPollfd(mPollfd_t& dest): mArray(dest) {}
+ void operator()(const sh_poll_s& row);
+ };
+
+ 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);
+ }
+
+ static bool onlyFiredEvents(const pollfd& a)
+ {
+ return a.events==0 ? false : true;
+ }
+
+ //todo: maybe we could simplify mListActiveTimer to hold only the handle and the countdown ....
+ mPollfd_t mfdPollingArray;
+ mListPoll_t mListPoll;
+ std::list<timer_s> mListTimer; //!<list of all timers
+ std::list<timer_s> mListActiveTimer; //!<list of all currently active timers
+ sh_timerHandle_t mNextTimer;
+ sh_timerHandle_t mLastInsertedHandle;
+ sh_pollHandle_t mLastInsertedPollHandle;
+ timespec mTimeout;
+ bool mDispatch;
+ bool mRecreatePollfds;
+};
+
+/**
+ * classic functor for the BasicTimerCallback
+ */
+class TBasicTimerCallback
+{
+public:
+ virtual void Call (const sh_timerHandle_t handle, void* userData)=0;
+ virtual ~TBasicTimerCallback(){};
+};
+
+class shPollPrepare
+{
+public:
+ virtual void Call (const sh_pollHandle_t handle, void* userData)=0;
+ virtual ~shPollPrepare(){};
+};
+
+class shPollFired
+{
+public:
+ virtual void Call(const pollfd pollfd,const sh_pollHandle_t handle, void* userData)=0;
+ virtual ~ shPollFired(){};
+};
+
+class shPollCheck
+{
+public:
+ virtual bool Call (const sh_pollHandle_t handle, void* userData)=0;
+ virtual ~ shPollCheck(){};
+};
+
+class shPollDispatch
+{
+public:
+ virtual bool Call (const sh_pollHandle_t handle, void* userData)=0;
+ virtual ~ shPollDispatch(){};
+};
+
+/**
+ * template to create the functor for a class
+ */
+template <class TClass> class TSpecificTimerCallback : public TBasicTimerCallback
+{
+private:
+ TClass* mInstance;
+ void (TClass::*mFunction)(sh_timerHandle_t handle, void* userData);
+
+public:
+ TSpecificTimerCallback(TClass* instance, void(TClass::*function)(sh_timerHandle_t handle, void* userData))
+ :mInstance(instance), mFunction(function){};
+
+ virtual void Call(sh_timerHandle_t handle, void* userData)
+ {
+ (*mInstance.*mFunction)(handle, userData);
+ }
+};
+
+/**
+ * template to create the functor for a class
+ */
+template <class TClass> class shPollPrepare_T : public shPollPrepare
+{
+private:
+ TClass* mInstance;
+ void (TClass::*mFunction)(const sh_timerHandle_t handle, void* userData);
+
+public:
+ shPollPrepare_T(TClass* instance, void(TClass::*function)(const sh_timerHandle_t handle, void* userData))
+ :mInstance(instance), mFunction(function){};
+
+ virtual void Call(const sh_timerHandle_t handle, void* userData)
+ {
+ (*mInstance.*mFunction)(handle,userData);
+ };
+};
+
+template <class TClass> class shPollFired_T : public shPollFired
+{
+private:
+ TClass* mInstance;
+ void (TClass::*mFunction)(const pollfd pollfd,const sh_pollHandle_t handle, void* userData);
+
+public:
+ shPollFired_T(TClass* instance, void(TClass::*function)(const pollfd pollfd,const sh_pollHandle_t handle, void* userData))
+ :mInstance(instance), mFunction(function){};
+
+ virtual void Call(const pollfd pollfd,const sh_pollHandle_t handle, void* userData)
+ {
+ (*mInstance.*mFunction)(pollfd,handle,userData);
+ };
+};
+
+template <class TClass> class shPollCheck_T : public shPollCheck
+{
+private:
+ TClass* mInstance;
+ bool (TClass::*mFunction)(const sh_pollHandle_t handle, void* userData);
+
+public:
+ shPollCheck_T(TClass* instance, bool(TClass::*function)(const sh_pollHandle_t handle, void* userData))
+ :mInstance(instance), mFunction(function){};
+
+ virtual bool Call(const sh_pollHandle_t handle, void* userData)
+ {
+ return (*mInstance.*mFunction)(handle,userData);
+ };
+};
+
+template <class TClass> class shPollDispatch_T : public shPollDispatch
+{
+private:
+ TClass* mInstance;
+ bool (TClass::*mFunction)(const sh_pollHandle_t handle, void* userData);
+
+public:
+ shPollDispatch_T(TClass* instance, bool (TClass::*function)(const sh_pollHandle_t handle, void* userData))
+ :mInstance(instance), mFunction(function){};
+
+ virtual bool Call(const sh_pollHandle_t handle, void* userData)
+ {
+ return (*mInstance.*mFunction)(handle,userData);
+ };
+};
+} /* namespace am */
+#endif /* SOCKETHANDLER_H_ */