* enhanced documentation
[profile/ivi/genivi/genivi-audio-manager.git] / include / shared / CAmSocketHandler.h
1 /**
2  *  Copyright (C) 2012, BMW AG
3  *
4  *  \author Christian Mueller, christian.ei.mueller@bmw.de BMW 2011,2012
5  *
6  *  \copyright
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.
14  *
15  *  \file CAmSocketHandler.h
16  *  For further information see http://www.genivi.org/.
17  */
18
19 #ifndef SOCKETHANDLER_H_
20 #define SOCKETHANDLER_H_
21
22 #include "audiomanagertypes.h"
23 #include <sys/socket.h>
24 #include <sys/time.h>
25 #include <stdint.h>
26 #include <sys/poll.h>
27 #include <list>
28 #include <map>
29 #include <signal.h>
30
31 namespace am
32 {
33
34 static volatile sig_atomic_t gDispatchDone = 0; //this global is used to stop the mainloop
35
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
38
39 class IAmShPollPrepare;
40 class IAmShPollCheck;
41 class IAmShPollFired;
42 class IAmShPollDispatch;
43 class IAmShTimerCallBack;
44
45 /**
46  * The am::CAmSocketHandler implements a mainloop for the AudioManager. Plugins and different parts of the AudioManager add their filedescriptors to the handler
47  * to get called on communication of the filedescriptors.\n
48  * More information can be found here : \ref mainl
49  */
50 class CAmSocketHandler
51 {
52 public:
53     CAmSocketHandler();
54     ~CAmSocketHandler();
55
56     am_Error_e addFDPoll(const int fd, const short event, IAmShPollPrepare *prepare, IAmShPollFired *fired, IAmShPollCheck *check, IAmShPollDispatch *dispatch, void* userData, sh_pollHandle_t& handle);
57     am_Error_e removeFDPoll(const sh_pollHandle_t handle);
58     am_Error_e updateEventFlags(const sh_pollHandle_t handle, const short events);
59     am_Error_e addTimer(const timespec timeouts, IAmShTimerCallBack*& callback, sh_timerHandle_t& handle, void* userData);
60     am_Error_e removeTimer(const sh_timerHandle_t handle);
61     am_Error_e restartTimer(const sh_timerHandle_t handle, const timespec timeouts);
62     am_Error_e stopTimer(const sh_timerHandle_t handle);
63     void start_listenting();
64     void stop_listening();
65 private:
66     struct sh_timer_s //!<struct that holds information of timers
67     {
68         sh_timerHandle_t handle; //!<the handle of the timer
69         timespec countdown; //!<the countdown, this value is decreased every time the timer is up
70         timespec timeout; //!<the original timer value
71         IAmShTimerCallBack* callback; //!<the callbackfunction
72         void * userData; //!<saves a void pointer together with the rest.
73     };
74
75     class CAmShSubstractTime //!<functor to easy substract from each countdown value
76     {
77     private:
78         timespec param;
79     public:
80         CAmShSubstractTime(timespec param) :
81                 param(param)
82         {
83         }
84         void operator()(sh_timer_s& t) const;
85     };
86
87     struct sh_poll_s //!<struct that holds information about polls
88     {
89         sh_pollHandle_t handle; //!<handle to uniquely adress a filedesriptor
90         IAmShPollPrepare *prepareCB;
91         IAmShPollFired *firedCB;
92         IAmShPollCheck *checkCB;
93         IAmShPollDispatch *dispatchCB;
94         pollfd pollfdValue; //!<the array for polling the filedescriptors
95         void *userData; //!<userdata saved together with the callback.
96     };
97
98     typedef std::vector<pollfd> mListPollfd_t; //!<vector of filedescriptors
99     typedef std::vector<sh_poll_s> mListPoll_t; //!<list for the callbacks
100
101     class CAmShCopyPollfd
102     {
103     private:
104         mListPollfd_t& mArray;
105     public:
106         CAmShCopyPollfd(mListPollfd_t& dest) :
107                 mArray(dest)
108         {
109         }
110         void operator()(const sh_poll_s& row);
111     };
112
113     bool fdIsValid(const int fd) const;
114     void initTimer();
115     void timerUp();
116     int timespec2ms(const timespec& time);
117     timespec* insertTime(timespec& buffertime);
118     static bool compareCountdown(const sh_timer_s& a, const sh_timer_s& b)
119     {
120         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));
121     }
122
123     static bool onlyFiredEvents(const pollfd& a)
124     {
125         return (a.revents == 0 ? false : true);
126     }
127
128     //todo: maybe we could simplify mListActiveTimer to hold only the handle and the countdown ....
129     mListPollfd_t mfdPollingArray;
130     mListPoll_t mListPoll;
131     std::list<sh_timer_s> mListTimer; //!<list of all timers
132     std::list<sh_timer_s> mListActiveTimer; //!<list of all currently active timers
133     sh_timerHandle_t mNextTimer;
134     sh_timerHandle_t mLastInsertedHandle;
135     sh_pollHandle_t mLastInsertedPollHandle;
136     bool mRecreatePollfds;
137     timespec mTimeout;
138 };
139
140 /**
141  * prototype for the timer callback
142  */
143 class IAmShTimerCallBack
144 {
145 public:
146     virtual void Call(const sh_timerHandle_t handle, void* userData)=0;
147     virtual ~IAmShTimerCallBack(){};
148 };
149
150 /**
151  * prototype for poll prepared callback
152  */
153 class IAmShPollPrepare
154 {
155 public:
156     virtual void Call(const sh_pollHandle_t handle, void* userData)=0;
157     virtual ~IAmShPollPrepare(){};
158 };
159
160 /**
161  * prototype for poll fired callback
162  */
163 class IAmShPollFired
164 {
165 public:
166     virtual void Call(const pollfd pollfd, const sh_pollHandle_t handle, void* userData)=0;
167     virtual ~ IAmShPollFired(){};
168 };
169
170 /**
171  * prototype for poll check callback
172  */
173 class IAmShPollCheck
174 {
175 public:
176     virtual bool Call(const sh_pollHandle_t handle, void* userData)=0;
177     virtual ~ IAmShPollCheck(){};
178 };
179
180 /**
181  * prototype for dispatch callback
182  */
183 class IAmShPollDispatch
184 {
185 public:
186     virtual bool Call(const sh_pollHandle_t handle, void* userData)=0;
187     virtual ~ IAmShPollDispatch(){};
188 };
189
190 /**
191  * template to create the functor for a class
192  */
193 template<class TClass> class TAmShTimerCallBack: public IAmShTimerCallBack
194 {
195 private:
196     TClass* mInstance;
197     void (TClass::*mFunction)(sh_timerHandle_t handle, void* userData);
198
199 public:
200     TAmShTimerCallBack(TClass* instance, void (TClass::*function)(sh_timerHandle_t handle, void* userData)) :
201             mInstance(instance), //
202             mFunction(function){};
203
204     virtual void Call(sh_timerHandle_t handle, void* userData)
205     {
206         (*mInstance.*mFunction)(handle, userData);
207     }
208 };
209
210 /**
211  * template for a callback
212  */
213 template<class TClass> class TAmShPollPrepare: public IAmShPollPrepare
214 {
215 private:
216     TClass* mInstance;
217     void (TClass::*mFunction)(const sh_timerHandle_t handle, void* userData);
218
219 public:
220     TAmShPollPrepare(TClass* instance, void (TClass::*function)(const sh_timerHandle_t handle, void* userData)) :
221             mInstance(instance), //
222             mFunction(function){};
223
224     virtual void Call(const sh_timerHandle_t handle, void* userData)
225     {
226         (*mInstance.*mFunction)(handle, userData);
227     }
228     ;
229 };
230
231 /**
232  * template for a callback
233  */
234 template<class TClass> class TAmShPollFired: public IAmShPollFired
235 {
236 private:
237     TClass* mInstance;
238     void (TClass::*mFunction)(const pollfd pollfd, const sh_pollHandle_t handle, void* userData);
239
240 public:
241     TAmShPollFired(TClass* instance, void (TClass::*function)(const pollfd pollfd, const sh_pollHandle_t handle, void* userData)) :
242             mInstance(instance), //
243             mFunction(function){};
244
245     virtual void Call(const pollfd pollfd, const sh_pollHandle_t handle, void* userData)
246     {
247         (*mInstance.*mFunction)(pollfd, handle, userData);
248     }
249     ;
250 };
251
252 /**
253  * template for a callback
254  */
255 template<class TClass> class TAmShPollCheck: public IAmShPollCheck
256 {
257 private:
258     TClass* mInstance;
259     bool (TClass::*mFunction)(const sh_pollHandle_t handle, void* userData);
260
261 public:
262     TAmShPollCheck(TClass* instance, bool (TClass::*function)(const sh_pollHandle_t handle, void* userData)) :
263             mInstance(instance), //
264             mFunction(function){};
265
266     virtual bool Call(const sh_pollHandle_t handle, void* userData)
267     {
268         return ((*mInstance.*mFunction)(handle, userData));
269     }
270     ;
271 };
272
273 /**
274  * template for a callback
275  */
276 template<class TClass> class TAmShPollDispatch: public IAmShPollDispatch
277 {
278 private:
279     TClass* mInstance;
280     bool (TClass::*mFunction)(const sh_pollHandle_t handle, void* userData);
281
282 public:
283     TAmShPollDispatch(TClass* instance, bool (TClass::*function)(const sh_pollHandle_t handle, void* userData)) :
284             mInstance(instance), //
285             mFunction(function){};
286
287     virtual bool Call(const sh_pollHandle_t handle, void* userData)
288     {
289         return ((*mInstance.*mFunction)(handle, userData));
290     }
291     ;
292 };
293 } /* namespace am */
294 #endif /* SOCKETHANDLER_H_ */