2 * Copyright (C) 2012, BMW AG
4 * \author Christian Mueller, christian.ei.mueller@bmw.de BMW 2011,2012
7 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction,
8 * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
9 * subject to the following conditions:
10 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
12 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
13 * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
15 * \file CAmSocketHandler.h
16 * For further information see http://www.genivi.org/.
19 #ifndef SOCKETHANDLER_H_
20 #define SOCKETHANDLER_H_
22 #include "audiomanagertypes.h"
23 #include <sys/socket.h>
30 #include <iostream> //todo: remove me
34 #define MAX_NS 1000000000L
36 static volatile sig_atomic_t gDispatchDone = 1; //this global is used to stop the mainloop
38 typedef uint16_t sh_timerHandle_t; //!<this is a handle for a timer to be used with the SocketHandler
39 typedef uint16_t sh_pollHandle_t; //!<this is a handle for a filedescriptor to be used with the SocketHandler
42 * prototype for poll prepared callback
44 class IAmShPollPrepare
47 virtual void Call(const sh_pollHandle_t handle, void* userData)=0;
48 virtual ~IAmShPollPrepare()
55 * prototype for poll fired callback
60 virtual void Call(const pollfd pollfd, const sh_pollHandle_t handle, void* userData)=0;
61 virtual ~ IAmShPollFired()
68 * prototype for poll check callback
73 virtual bool Call(const sh_pollHandle_t handle, void* userData)=0;
74 virtual ~ IAmShPollCheck()
81 * prototype for dispatch callback
83 class IAmShPollDispatch
86 virtual bool Call(const sh_pollHandle_t handle, void* userData)=0;
87 virtual ~ IAmShPollDispatch()
94 * prototype for the timer callback
96 class IAmShTimerCallBack
99 virtual void Call(const sh_timerHandle_t handle, void* userData)=0;
100 virtual ~IAmShTimerCallBack()
107 * The am::CAmSocketHandler implements a mainloop for the AudioManager. Plugins and different parts of the AudioManager add their filedescriptors to the handler
108 * to get called on communication of the filedescriptors.\n
109 * More information can be found here : \ref mainl
111 class CAmSocketHandler
117 am_Error_e addFDPoll(const int fd, const short event, IAmShPollPrepare *prepare, IAmShPollFired *fired, IAmShPollCheck *check, IAmShPollDispatch *dispatch, void* userData, sh_pollHandle_t& handle);
118 am_Error_e removeFDPoll(const sh_pollHandle_t handle);
119 am_Error_e updateEventFlags(const sh_pollHandle_t handle, const short events);
120 am_Error_e addTimer(const timespec timeouts, IAmShTimerCallBack* callback, sh_timerHandle_t& handle, void* userData);
121 am_Error_e removeTimer(const sh_timerHandle_t handle);
122 am_Error_e restartTimer(const sh_timerHandle_t handle);
123 am_Error_e updateTimer(const sh_timerHandle_t handle, const timespec timeouts);
124 am_Error_e stopTimer(const sh_timerHandle_t handle);
125 void start_listenting();
126 void stop_listening();
128 struct sh_timer_s //!<struct that holds information of timers
130 sh_timerHandle_t handle; //!<the handle of the timer
131 timespec countdown; //!<the countdown, this value is decreased every time the timer is up
132 IAmShTimerCallBack* callback; //!<the callbackfunction
133 void * userData; //!<saves a void pointer together with the rest.
136 typedef std::reverse_iterator<sh_timer_s> rListTimerIter; //!<typedef for reverseiterator on timer lists
138 struct sh_poll_s //!<struct that holds information about polls
140 sh_pollHandle_t handle; //!<handle to uniquely adress a filedesriptor
141 IAmShPollPrepare *prepareCB; //!<pointer to preperation callback
142 IAmShPollFired *firedCB; //!<pointer to fired callback
143 IAmShPollCheck *checkCB; //!< pointer to check callback
144 IAmShPollDispatch *dispatchCB; //!<pointer to dispatch callback
145 pollfd pollfdValue; //!<the array for polling the filedescriptors
146 void *userData; //!<userdata saved together with the callback.
149 typedef std::vector<pollfd> mListPollfd_t; //!<vector of filedescriptors
150 typedef std::vector<sh_poll_s> mListPoll_t; //!<list for the callbacks
152 bool fdIsValid(const int fd) const;
154 void timerCorrection();
155 timespec* insertTime(timespec& buffertime);
158 * compares countdown values
161 * @return true if b greater a
163 inline static bool compareCountdown(const sh_timer_s& a, const sh_timer_s& b)
165 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));
172 * @return subtracted value
174 inline static timespec timespecSub(const timespec& a, const timespec& b)
178 if ((a.tv_sec < b.tv_sec) || ((a.tv_sec == b.tv_sec) && (a.tv_nsec <= b.tv_nsec)))
180 result.tv_sec = result.tv_nsec = 0;
184 result.tv_sec = a.tv_sec - b.tv_sec;
185 if (a.tv_nsec < b.tv_nsec)
187 result.tv_nsec = a.tv_nsec + MAX_NS - b.tv_nsec;
188 result.tv_sec--; /* Borrow a second. */
192 result.tv_nsec = a.tv_nsec - b.tv_nsec;
199 * adds timespec values
202 * @return the added values
204 inline timespec timespecAdd(const timespec& a, const timespec& b)
207 result.tv_sec = a.tv_sec + b.tv_sec;
208 result.tv_nsec = a.tv_nsec + b.tv_nsec;
209 if (result.tv_nsec >= MAX_NS)
212 result.tv_nsec = result.tv_nsec - MAX_NS;
218 * comapares timespec values
223 inline int timespecCompare(const timespec& a, const timespec& b)
226 if (a.tv_sec < b.tv_sec)
229 else if (a.tv_sec > b.tv_sec)
232 else if (a.tv_nsec < b.tv_nsec)
235 else if (a.tv_nsec > b.tv_nsec)
243 * functor to return all fired events
247 inline static bool eventFired(const pollfd& a)
249 return (a.revents == 0 ? false : true);
253 * functor to help find the items that do not need dispatching
257 inline static bool noDispatching(const sh_poll_s& a)
259 //remove from list of there is no checkCB
262 return (!a.checkCB->Call(a.handle, a.userData));
266 * checks if dispatching is already finished
270 inline static bool dispatchingFinished(const sh_poll_s& a)
272 //remove from list of there is no dispatchCB
275 return (!a.dispatchCB->Call(a.handle, a.userData));
278 class CAmShCopyPollfd //!< functor to copy filedescriptors into the poll array
281 mListPollfd_t& mArray;
283 CAmShCopyPollfd(mListPollfd_t& dest) :
287 void operator()(const sh_poll_s& row)
289 pollfd temp = row.pollfdValue;
291 mArray.push_back(temp);
295 class CAmShCallFire //!< functor to call the firecallbacks
302 void operator()(sh_poll_s& row)
304 row.firedCB->Call(row.pollfdValue, row.handle, row.userData);
308 class CAmShCallPrep //!< functor to call the preparation callbacks
315 void operator()(sh_poll_s& row)
318 row.prepareCB->Call(row.handle, row.userData);
322 class CAmShCallTimer //!<functor to call a timer
329 void operator()(sh_timer_s& row)
331 row.callback->Call(row.handle, row.userData);
335 class CAmShCountdownUp //!<functor that checks if a timer is up
340 CAmShCountdownUp(const timespec& differenceTime) :
341 mDiffTime(differenceTime)
345 bool operator()(const sh_timer_s& row)
347 timespec sub = timespecSub(row.countdown, mDiffTime);
348 if (sub.tv_nsec == 0 && sub.tv_sec == 0)
354 class CAmShCountdownZero //!<functor that checks if a timer is zero
361 bool operator()(const sh_timer_s& row)
363 if (row.countdown.tv_nsec == 0 && row.countdown.tv_sec == 0)
369 class CAmShSubstractTime //!<functor to easy substract from each countdown value
374 CAmShSubstractTime(timespec param) :
378 inline void operator()(sh_timer_s& t)
380 t.countdown = timespecSub(t.countdown, param);
384 mListPollfd_t mfdPollingArray; //!<the polling array for ppoll
385 mListPoll_t mListPoll; //!<list that holds all information for the ppoll
386 std::list<sh_timer_s> mListTimer; //!<list of all timers
387 std::list<sh_timer_s> mListActiveTimer; //!<list of all currently active timers
388 sh_timerHandle_t mLastInsertedHandle; //!<keeps track of the last inserted timer handle
389 sh_pollHandle_t mLastInsertedPollHandle; //!<keeps track of the last inserted poll handle
390 bool mRecreatePollfds; //!<when this is true, the poll list needs to be recreated
391 timespec mStartTime; //!<here the actual time is saved for timecorrection
393 // void debugPrintTimerList ()
395 // std::list<sh_timer_s>::iterator it(mListActiveTimer.begin());
396 // for(;it!=mListActiveTimer.end();++it)
398 // std::cout<< "Handle " << it->handle << "sec " << it->countdown.tv_sec << "nsec " << it->countdown.tv_nsec<<std::endl;
405 * template to create the functor for a class
407 template<class TClass> class TAmShTimerCallBack: public IAmShTimerCallBack
411 void (TClass::*mFunction)(sh_timerHandle_t handle, void* userData);
414 TAmShTimerCallBack(TClass* instance, void (TClass::*function)(sh_timerHandle_t handle, void* userData)) :
415 mInstance(instance), //
421 virtual void Call(sh_timerHandle_t handle, void* userData)
423 (*mInstance.*mFunction)(handle, userData);
428 * template for a callback
430 template<class TClass> class TAmShPollPrepare: public IAmShPollPrepare
434 void (TClass::*mFunction)(const sh_timerHandle_t handle, void* userData);
437 TAmShPollPrepare(TClass* instance, void (TClass::*function)(const sh_timerHandle_t handle, void* userData)) :
438 mInstance(instance), //
444 virtual void Call(const sh_timerHandle_t handle, void* userData)
446 (*mInstance.*mFunction)(handle, userData);
451 /**make private, not public
452 * template for a callback
454 template<class TClass> class TAmShPollFired: public IAmShPollFired
458 void (TClass::*mFunction)(const pollfd pollfd, const sh_pollHandle_t handle, void* userData);
461 TAmShPollFired(TClass* instance, void (TClass::*function)(const pollfd pollfd, const sh_pollHandle_t handle, void* userData)) :
462 mInstance(instance), //
468 virtual void Call(const pollfd pollfd, const sh_pollHandle_t handle, void* userData)
470 (*mInstance.*mFunction)(pollfd, handle, userData);
476 * template for a callback
478 template<class TClass> class TAmShPollCheck: public IAmShPollCheck
482 bool (TClass::*mFunction)(const sh_pollHandle_t handle, void* userData);
485 TAmShPollCheck(TClass* instance, bool (TClass::*function)(const sh_pollHandle_t handle, void* userData)) :
486 mInstance(instance), //
492 virtual bool Call(const sh_pollHandle_t handle, void* userData)
494 return ((*mInstance.*mFunction)(handle, userData));
500 * template for a callback
502 template<class TClass> class TAmShPollDispatch: public IAmShPollDispatch
506 bool (TClass::*mFunction)(const sh_pollHandle_t handle, void* userData);
509 TAmShPollDispatch(TClass* instance, bool (TClass::*function)(const sh_pollHandle_t handle, void* userData)) :
510 mInstance(instance), //
516 virtual bool Call(const sh_pollHandle_t handle, void* userData)
518 return ((*mInstance.*mFunction)(handle, userData));
523 #endif /* SOCKETHANDLER_H_ */