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