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 typedef uint16_t sh_timerHandle_t; //!<this is a handle for a timer to be used with the SocketHandler
37 typedef uint16_t sh_pollHandle_t; //!<this is a handle for a filedescriptor to be used with the SocketHandler
40 * prototype for poll prepared callback
42 class IAmShPollPrepare
45 virtual void Call(const sh_pollHandle_t handle, void* userData)=0;
46 virtual ~IAmShPollPrepare()
53 * prototype for poll fired callback
58 virtual void Call(const pollfd pollfd, const sh_pollHandle_t handle, void* userData)=0;
59 virtual ~ IAmShPollFired()
66 * prototype for poll check callback
71 virtual bool Call(const sh_pollHandle_t handle, void* userData)=0;
72 virtual ~ IAmShPollCheck()
79 * prototype for dispatch callback
81 class IAmShPollDispatch
84 virtual bool Call(const sh_pollHandle_t handle, void* userData)=0;
85 virtual ~ IAmShPollDispatch()
92 * prototype for the timer callback
94 class IAmShTimerCallBack
97 virtual void Call(const sh_timerHandle_t handle, void* userData)=0;
98 virtual ~IAmShTimerCallBack()
105 * The am::CAmSocketHandler implements a mainloop for the AudioManager. Plugins and different parts of the AudioManager add their filedescriptors to the handler
106 * to get called on communication of the filedescriptors.\n
107 * More information can be found here : \ref mainl
109 class CAmSocketHandler
112 template<class TClass> class TAmShPollFired: public IAmShPollFired
116 void (TClass::*mFunction)(const pollfd pollfd, const sh_pollHandle_t handle, void* userData);
119 TAmShPollFired(TClass* instance, void (TClass::*function)(const pollfd pollfd, const sh_pollHandle_t handle, void* userData)) :
120 mInstance(instance), //
121 mFunction(function) {};
123 virtual void Call(const pollfd pollfd, const sh_pollHandle_t handle, void* userData)
125 (*mInstance.*mFunction)(pollfd, handle, userData);
129 template<class TClass> class TAmShPollCheck: public IAmShPollCheck
133 bool (TClass::*mFunction)(const sh_pollHandle_t handle, void* userData);
136 TAmShPollCheck(TClass* instance, bool (TClass::*function)(const sh_pollHandle_t handle, void* userData)) :
137 mInstance(instance), //
138 mFunction(function) {};
140 virtual bool Call(const sh_pollHandle_t handle, void* userData)
142 return ((*mInstance.*mFunction)(handle, userData));
149 am_Error_e addFDPoll(const int fd, const short event, IAmShPollPrepare *prepare, IAmShPollFired *fired, IAmShPollCheck *check, IAmShPollDispatch *dispatch, void* userData, sh_pollHandle_t& handle);
150 am_Error_e removeFDPoll(const sh_pollHandle_t handle);
151 am_Error_e updateEventFlags(const sh_pollHandle_t handle, const short events);
152 am_Error_e addTimer(const timespec timeouts, IAmShTimerCallBack* callback, sh_timerHandle_t& handle, void* userData);
153 am_Error_e removeTimer(const sh_timerHandle_t handle);
154 am_Error_e restartTimer(const sh_timerHandle_t handle);
155 am_Error_e updateTimer(const sh_timerHandle_t handle, const timespec timeouts);
156 am_Error_e stopTimer(const sh_timerHandle_t handle);
157 void start_listenting();
158 void stop_listening();
159 void exit_mainloop();
160 void receiverCallback(const pollfd pollfd, const sh_pollHandle_t handle, void* userData)
166 bool checkerCallback(const sh_pollHandle_t handle, void* userData)
173 TAmShPollFired<CAmSocketHandler> receiverCallbackT;
174 TAmShPollCheck<CAmSocketHandler> checkerCallbackT;
178 static CAmSocketHandler* mInstance;
180 int mDispatchDone; //this starts / stops the mainloop
181 struct sh_timer_s //!<struct that holds information of timers
183 sh_timerHandle_t handle; //!<the handle of the timer
184 timespec countdown; //!<the countdown, this value is decreased every time the timer is up
185 IAmShTimerCallBack* callback; //!<the callbackfunction
186 void * userData; //!<saves a void pointer together with the rest.
189 typedef std::reverse_iterator<sh_timer_s> rListTimerIter; //!<typedef for reverseiterator on timer lists
191 struct sh_poll_s //!<struct that holds information about polls
193 sh_pollHandle_t handle; //!<handle to uniquely adress a filedesriptor
194 IAmShPollPrepare *prepareCB; //!<pointer to preperation callback
195 IAmShPollFired *firedCB; //!<pointer to fired callback
196 IAmShPollCheck *checkCB; //!< pointer to check callback
197 IAmShPollDispatch *dispatchCB; //!<pointer to dispatch callback
198 pollfd pollfdValue; //!<the array for polling the filedescriptors
199 void *userData; //!<userdata saved together with the callback.
202 typedef std::vector<pollfd> mListPollfd_t; //!<vector of filedescriptors
203 typedef std::vector<sh_poll_s> mListPoll_t; //!<list for the callbacks
205 bool fdIsValid(const int fd) const;
207 void timerCorrection();
208 timespec* insertTime(timespec& buffertime);
211 * compares countdown values
214 * @return true if b greater a
216 inline static bool compareCountdown(const sh_timer_s& a, const sh_timer_s& b)
218 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));
225 * @return subtracted value
227 inline static timespec timespecSub(const timespec& a, const timespec& b)
231 if ((a.tv_sec < b.tv_sec) || ((a.tv_sec == b.tv_sec) && (a.tv_nsec <= b.tv_nsec)))
233 result.tv_sec = result.tv_nsec = 0;
237 result.tv_sec = a.tv_sec - b.tv_sec;
238 if (a.tv_nsec < b.tv_nsec)
240 result.tv_nsec = a.tv_nsec + MAX_NS - b.tv_nsec;
241 result.tv_sec--; /* Borrow a second. */
245 result.tv_nsec = a.tv_nsec - b.tv_nsec;
252 * adds timespec values
255 * @return the added values
257 inline timespec timespecAdd(const timespec& a, const timespec& b)
260 result.tv_sec = a.tv_sec + b.tv_sec;
261 result.tv_nsec = a.tv_nsec + b.tv_nsec;
262 if (result.tv_nsec >= MAX_NS)
265 result.tv_nsec = result.tv_nsec - MAX_NS;
271 * comapares timespec values
276 inline int timespecCompare(const timespec& a, const timespec& b)
279 if (a.tv_sec < b.tv_sec)
282 else if (a.tv_sec > b.tv_sec)
285 else if (a.tv_nsec < b.tv_nsec)
288 else if (a.tv_nsec > b.tv_nsec)
296 * functor to return all fired events
300 inline static bool eventFired(const pollfd& a)
302 return (a.revents == 0 ? false : true);
306 * functor to help find the items that do not need dispatching
310 inline static bool noDispatching(const sh_poll_s& a)
312 //remove from list of there is no checkCB
315 return (!a.checkCB->Call(a.handle, a.userData));
319 * checks if dispatching is already finished
323 inline static bool dispatchingFinished(const sh_poll_s& a)
325 //remove from list of there is no dispatchCB
328 return (!a.dispatchCB->Call(a.handle, a.userData));
331 class CAmShCopyPollfd //!< functor to copy filedescriptors into the poll array
334 mListPollfd_t& mArray;
336 CAmShCopyPollfd(mListPollfd_t& dest) :
340 void operator()(const sh_poll_s& row)
342 pollfd temp = row.pollfdValue;
344 mArray.push_back(temp);
348 class CAmShCallFire //!< functor to call the firecallbacks
355 void operator()(sh_poll_s& row)
357 row.firedCB->Call(row.pollfdValue, row.handle, row.userData);
361 class CAmShCallPrep //!< functor to call the preparation callbacks
368 void operator()(sh_poll_s& row)
371 row.prepareCB->Call(row.handle, row.userData);
375 class CAmShCallTimer //!<functor to call a timer
382 void operator()(sh_timer_s& row)
384 row.callback->Call(row.handle, row.userData);
388 class CAmShCountdownUp //!<functor that checks if a timer is up
393 CAmShCountdownUp(const timespec& differenceTime) :
394 mDiffTime(differenceTime)
398 bool operator()(const sh_timer_s& row)
400 timespec sub = timespecSub(row.countdown, mDiffTime);
401 if (sub.tv_nsec == 0 && sub.tv_sec == 0)
407 class CAmShCountdownZero //!<functor that checks if a timer is zero
414 bool operator()(const sh_timer_s& row)
416 if (row.countdown.tv_nsec == 0 && row.countdown.tv_sec == 0)
422 class CAmShSubstractTime //!<functor to easy substract from each countdown value
427 CAmShSubstractTime(timespec param) :
431 inline void operator()(sh_timer_s& t)
433 t.countdown = timespecSub(t.countdown, param);
437 mListPollfd_t mfdPollingArray; //!<the polling array for ppoll
438 mListPoll_t mListPoll; //!<list that holds all information for the ppoll
439 std::list<sh_timer_s> mListTimer; //!<list of all timers
440 std::list<sh_timer_s> mListActiveTimer; //!<list of all currently active timers
441 sh_timerHandle_t mLastInsertedHandle; //!<keeps track of the last inserted timer handle
442 sh_pollHandle_t mLastInsertedPollHandle; //!<keeps track of the last inserted poll handle
443 bool mRecreatePollfds; //!<when this is true, the poll list needs to be recreated
444 timespec mStartTime; //!<here the actual time is saved for timecorrection
446 // void debugPrintTimerList ()
448 // std::list<sh_timer_s>::iterator it(mListActiveTimer.begin());
449 // for(;it!=mListActiveTimer.end();++it)
451 // std::cout<< "Handle " << it->handle << "sec " << it->countdown.tv_sec << "nsec " << it->countdown.tv_nsec<<std::endl;
458 * template to create the functor for a class
460 template<class TClass> class TAmShTimerCallBack: public IAmShTimerCallBack
464 void (TClass::*mFunction)(sh_timerHandle_t handle, void* userData);
467 TAmShTimerCallBack(TClass* instance, void (TClass::*function)(sh_timerHandle_t handle, void* userData)) :
468 mInstance(instance), //
474 virtual void Call(sh_timerHandle_t handle, void* userData)
476 (*mInstance.*mFunction)(handle, userData);
481 * template for a callback
483 template<class TClass> class TAmShPollPrepare: public IAmShPollPrepare
487 void (TClass::*mFunction)(const sh_timerHandle_t handle, void* userData);
490 TAmShPollPrepare(TClass* instance, void (TClass::*function)(const sh_timerHandle_t handle, void* userData)) :
491 mInstance(instance), //
497 virtual void Call(const sh_timerHandle_t handle, void* userData)
499 (*mInstance.*mFunction)(handle, userData);
504 /**make private, not public
505 * template for a callback
507 template<class TClass> class TAmShPollFired: public IAmShPollFired
511 void (TClass::*mFunction)(const pollfd pollfd, const sh_pollHandle_t handle, void* userData);
514 TAmShPollFired(TClass* instance, void (TClass::*function)(const pollfd pollfd, const sh_pollHandle_t handle, void* userData)) :
515 mInstance(instance), //
521 virtual void Call(const pollfd pollfd, const sh_pollHandle_t handle, void* userData)
523 (*mInstance.*mFunction)(pollfd, handle, userData);
529 * template for a callback
531 template<class TClass> class TAmShPollCheck: public IAmShPollCheck
535 bool (TClass::*mFunction)(const sh_pollHandle_t handle, void* userData);
538 TAmShPollCheck(TClass* instance, bool (TClass::*function)(const sh_pollHandle_t handle, void* userData)) :
539 mInstance(instance), //
545 virtual bool Call(const sh_pollHandle_t handle, void* userData)
547 return ((*mInstance.*mFunction)(handle, userData));
553 * template for a callback
555 template<class TClass> class TAmShPollDispatch: public IAmShPollDispatch
559 bool (TClass::*mFunction)(const sh_pollHandle_t handle, void* userData);
562 TAmShPollDispatch(TClass* instance, bool (TClass::*function)(const sh_pollHandle_t handle, void* userData)) :
563 mInstance(instance), //
569 virtual bool Call(const sh_pollHandle_t handle, void* userData)
571 return ((*mInstance.*mFunction)(handle, userData));
576 #endif /* SOCKETHANDLER_H_ */