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>
33 static volatile sig_atomic_t gDispatchDone = 0; //this global is used to stop the mainloop
35 typedef uint16_t sh_timerHandle_t; //!<this is a handle for a timer to be used with the SocketHandler
36 typedef uint16_t sh_pollHandle_t; //!<this is a handle for a filedescriptor to be used with the SocketHandler
39 * prototype for poll prepared callback
41 class IAmShPollPrepare
44 virtual void Call(const sh_pollHandle_t handle, void* userData)=0;
45 virtual ~IAmShPollPrepare(){};
49 * prototype for poll fired callback
54 virtual void Call(const pollfd pollfd, const sh_pollHandle_t handle, void* userData)=0;
55 virtual ~ IAmShPollFired(){};
59 * prototype for poll check callback
64 virtual bool Call(const sh_pollHandle_t handle, void* userData)=0;
65 virtual ~ IAmShPollCheck(){};
69 * prototype for dispatch callback
71 class IAmShPollDispatch
74 virtual bool Call(const sh_pollHandle_t handle, void* userData)=0;
75 virtual ~ IAmShPollDispatch(){};
79 * prototype for the timer callback
81 class IAmShTimerCallBack
84 virtual void Call(const sh_timerHandle_t handle, void* userData)=0;
85 virtual ~IAmShTimerCallBack(){};
89 * The am::CAmSocketHandler implements a mainloop for the AudioManager. Plugins and different parts of the AudioManager add their filedescriptors to the handler
90 * to get called on communication of the filedescriptors.\n
91 * More information can be found here : \ref mainl
93 class CAmSocketHandler
99 am_Error_e addFDPoll(const int fd, const short event, IAmShPollPrepare *prepare, IAmShPollFired *fired, IAmShPollCheck *check, IAmShPollDispatch *dispatch, void* userData, sh_pollHandle_t& handle);
100 am_Error_e removeFDPoll(const sh_pollHandle_t handle);
101 am_Error_e updateEventFlags(const sh_pollHandle_t handle, const short events);
102 am_Error_e addTimer(const timespec timeouts, IAmShTimerCallBack*& callback, sh_timerHandle_t& handle, void* userData);
103 am_Error_e removeTimer(const sh_timerHandle_t handle);
104 am_Error_e restartTimer(const sh_timerHandle_t handle, const timespec timeouts);
105 am_Error_e stopTimer(const sh_timerHandle_t handle);
106 void start_listenting();
107 void stop_listening();
109 struct sh_timer_s //!<struct that holds information of timers
111 sh_timerHandle_t handle; //!<the handle of the timer
112 timespec countdown; //!<the countdown, this value is decreased every time the timer is up
113 timespec timeout; //!<the original timer value
114 IAmShTimerCallBack* callback; //!<the callbackfunction
115 void * userData; //!<saves a void pointer together with the rest.
118 typedef std::reverse_iterator<sh_timer_s> rListTimerIter;
120 class CAmShSubstractTime //!<functor to easy substract from each countdown value
125 CAmShSubstractTime(timespec param) :
127 inline void operator()(sh_timer_s& t) const;
130 struct sh_poll_s //!<struct that holds information about polls
132 sh_pollHandle_t handle; //!<handle to uniquely adress a filedesriptor
133 IAmShPollPrepare *prepareCB;
134 IAmShPollFired *firedCB;
135 IAmShPollCheck *checkCB;
136 IAmShPollDispatch *dispatchCB;
137 pollfd pollfdValue; //!<the array for polling the filedescriptors
138 void *userData; //!<userdata saved together with the callback.
141 typedef std::vector<pollfd> mListPollfd_t; //!<vector of filedescriptors
142 typedef std::vector<sh_poll_s> mListPoll_t; //!<list for the callbacks
144 class CAmShCopyPollfd
147 mListPollfd_t& mArray;
149 CAmShCopyPollfd(mListPollfd_t& dest) :
151 void operator()(const sh_poll_s& row)
153 pollfd temp = row.pollfdValue;
155 mArray.push_back(temp);
159 class CAmShMatchingFd
164 CAmShMatchingFd(int fd, int eventFlag) :
166 mEventFlag(eventFlag)
168 bool operator()(const sh_poll_s& a)
170 return (((a.pollfdValue.fd == mFD) && (a.pollfdValue.events == mEventFlag)) ? true : false);
178 void operator()(sh_poll_s& row)
180 row.firedCB->Call(row.pollfdValue, row.handle, row.userData);
188 void operator()(sh_poll_s& row)
191 row.prepareCB->Call(row.handle, row.userData);
199 void operator()(sh_timer_s& row)
201 row.callback->Call(row.handle, row.userData);
205 class CAmShCountdownUp
208 CAmShCountdownUp(){};
209 bool operator()(sh_timer_s& row)
211 if (row.countdown.tv_nsec == 0 && row.countdown.tv_sec == 0)
217 class CAmShCountdownSame
220 sh_timer_s mCompareValue;
222 CAmShCountdownSame(sh_timer_s& a) :
225 bool operator()(const sh_timer_s& b)
227 return ((mCompareValue.countdown.tv_sec == b.countdown.tv_sec) && (mCompareValue.countdown.tv_nsec == b.countdown.tv_nsec) ? true : false);
231 bool fdIsValid(const int fd) const;
234 void timerCorrection();
235 int timespec2ms(const timespec& time);
236 timespec* insertTime(timespec& buffertime);
238 static bool compareCountdown(const sh_timer_s& a, const sh_timer_s& b)
240 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));
247 * @return subtracted value
249 static timespec timespecSub(const timespec& a, const timespec& b)
253 if ((a.tv_sec < b.tv_sec) || ((a.tv_sec == b.tv_sec) && (a.tv_nsec <= b.tv_nsec)))
255 result.tv_sec = result.tv_nsec = 0;
259 result.tv_sec = a.tv_sec - b.tv_sec;
260 if (a.tv_nsec < b.tv_nsec)
262 result.tv_nsec = a.tv_nsec + 1000000000L - b.tv_nsec;
263 result.tv_sec--; /* Borrow a second. */
267 result.tv_nsec = a.tv_nsec - b.tv_nsec;
273 static timespec timespecAdd(const timespec& a, const timespec b)
276 result.tv_sec = a.tv_sec + b.tv_sec;
277 result.tv_nsec = a.tv_nsec + b.tv_nsec;
278 if (result.tv_nsec >= 1000000000L)
281 result.tv_nsec = result.tv_nsec - 1000000000L;
286 static int timespecCompare(const timespec& a, const timespec& b)
289 if (a.tv_sec < b.tv_sec)
292 else if (a.tv_sec > b.tv_sec)
295 else if (a.tv_nsec < b.tv_nsec)
298 else if (a.tv_nsec > b.tv_nsec)
305 inline static bool eventFired(const pollfd& a)
307 return (a.revents == 0 ? false : true);
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));
318 inline static bool dispatchingFinished(const sh_poll_s& a)
320 //remove from list of there is no dispatchCB
323 return (!a.dispatchCB->Call(a.handle, a.userData));
326 mListPollfd_t mfdPollingArray;
327 mListPoll_t mListPoll;
328 std::list<sh_timer_s> mListTimer; //!<list of all timers
329 std::list<sh_timer_s> mListActiveTimer; //!<list of all currently active timers
330 sh_timerHandle_t mLastInsertedHandle;
331 sh_pollHandle_t mLastInsertedPollHandle;
332 bool mRecreatePollfds;
338 * template to create the functor for a class
340 template<class TClass> class TAmShTimerCallBack: public IAmShTimerCallBack
344 void (TClass::*mFunction)(sh_timerHandle_t handle, void* userData);
347 TAmShTimerCallBack(TClass* instance, void (TClass::*function)(sh_timerHandle_t handle, void* userData)) :
348 mInstance(instance), //
349 mFunction(function){};
351 virtual void Call(sh_timerHandle_t handle, void* userData)
353 (*mInstance.*mFunction)(handle, userData);
358 * template for a callback
360 template<class TClass> class TAmShPollPrepare: public IAmShPollPrepare
364 void (TClass::*mFunction)(const sh_timerHandle_t handle, void* userData);
367 TAmShPollPrepare(TClass* instance, void (TClass::*function)(const sh_timerHandle_t handle, void* userData)) :
368 mInstance(instance), //
369 mFunction(function){};
371 virtual void Call(const sh_timerHandle_t handle, void* userData)
373 (*mInstance.*mFunction)(handle, userData);
378 * template for a callback
380 template<class TClass> class TAmShPollFired: public IAmShPollFired
384 void (TClass::*mFunction)(const pollfd pollfd, const sh_pollHandle_t handle, void* userData);
387 TAmShPollFired(TClass* instance, void (TClass::*function)(const pollfd pollfd, const sh_pollHandle_t handle, void* userData)) :
388 mInstance(instance), //
389 mFunction(function){};
391 virtual void Call(const pollfd pollfd, const sh_pollHandle_t handle, void* userData)
393 (*mInstance.*mFunction)(pollfd, handle, userData);
398 * template for a callback
400 template<class TClass> class TAmShPollCheck: public IAmShPollCheck
404 bool (TClass::*mFunction)(const sh_pollHandle_t handle, void* userData);
407 TAmShPollCheck(TClass* instance, bool (TClass::*function)(const sh_pollHandle_t handle, void* userData)) :
408 mInstance(instance), //
409 mFunction(function){};
411 virtual bool Call(const sh_pollHandle_t handle, void* userData)
413 return ((*mInstance.*mFunction)(handle, userData));
418 * template for a callback
420 template<class TClass> class TAmShPollDispatch: public IAmShPollDispatch
424 bool (TClass::*mFunction)(const sh_pollHandle_t handle, void* userData);
427 TAmShPollDispatch(TClass* instance, bool (TClass::*function)(const sh_pollHandle_t handle, void* userData)) :
428 mInstance(instance), //
429 mFunction(function){};
431 virtual bool Call(const sh_pollHandle_t handle, void* userData)
433 return ((*mInstance.*mFunction)(handle, userData));
437 #endif /* SOCKETHANDLER_H_ */