Merge remote branch 'buildsau/master'
[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, BMW
5  *
6  *  \section license
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  */
16
17 #ifndef SOCKETHANDLER_H_
18 #define SOCKETHANDLER_H_
19
20 #include "audiomanagertypes.h"
21 #include <sys/socket.h>
22 #include <sys/time.h>
23 #include <stdint.h>
24 #include <sys/poll.h>
25 #include <list>
26 #include <map>
27 #include <signal.h>
28
29 namespace am
30 {
31
32 static volatile sig_atomic_t gDispatchDone = 0; //this global is used to stop the mainloop
33
34 typedef uint16_t sh_timerHandle_t; //!<this is a handle for a timer to be used with the SocketHandler
35 typedef uint16_t sh_pollHandle_t; //!<this is a handle for a filedescriptor to be used with the SocketHandler
36
37 class CAmShPollPrepare;
38 class CAmShPollCheck;
39 class CAmShPollFired;
40 class CAmShPollDispatch;
41 class CAmShTimerCallBack;
42
43 class CAmSocketHandler
44 {
45 public:
46     CAmSocketHandler();
47     virtual ~CAmSocketHandler();
48
49     am_Error_e addFDPoll(const int fd, const short event, CAmShPollPrepare *prepare, CAmShPollFired *fired, CAmShPollCheck *check, CAmShPollDispatch *dispatch, void* userData, sh_pollHandle_t& handle);
50     am_Error_e removeFDPoll(const sh_pollHandle_t handle);
51     am_Error_e updateEventFlags(const sh_pollHandle_t handle, const short events);
52     am_Error_e addTimer(const timespec timeouts, CAmShTimerCallBack*& callback, sh_timerHandle_t& handle, void* userData);
53     am_Error_e removeTimer(const sh_timerHandle_t handle);
54     am_Error_e restartTimer(const sh_timerHandle_t handle, const timespec timeouts);
55     am_Error_e stopTimer(const sh_timerHandle_t handle);
56     void start_listenting();
57     void stop_listening();
58 private:
59     struct sh_timer_s //!<struct that holds information of timers
60     {
61         sh_timerHandle_t handle; //!<the handle of the timer
62         timespec countdown; //!<the countdown, this value is decreased every time the timer is up
63         timespec timeout; //!<the original timer value
64         CAmShTimerCallBack* callback; //!<the callbackfunction
65         void * userData; //!<saves a void pointer together with the rest.
66     };
67
68     class CAmShSubstractTime //!<functor to easy substract from each countdown value
69     {
70     private:
71         timespec param;
72     public:
73         CAmShSubstractTime(timespec param) :
74                 param(param){}
75         void operator()(sh_timer_s& t) const;
76     };
77
78     struct sh_poll_s //!<struct that holds information about polls
79     {
80         sh_pollHandle_t handle; //!<handle to uniquely adress a filedesriptor
81         CAmShPollPrepare *prepareCB;
82         CAmShPollFired *firedCB;
83         CAmShPollCheck *checkCB;
84         CAmShPollDispatch *dispatchCB;
85         pollfd pollfdValue; //!<the array for polling the filedescriptors
86         void *userData; //!<userdata saved together with the callback.
87     };
88
89     typedef std::vector<pollfd> mListPollfd_t; //!<vector of filedescriptors
90     typedef std::vector<sh_poll_s> mListPoll_t; //!<list for the callbacks
91
92     class CAmShCopyPollfd
93     {
94     private:
95         mListPollfd_t& mArray;
96     public:
97         CAmShCopyPollfd(mListPollfd_t& dest) :
98                 mArray(dest){}
99         void operator()(const sh_poll_s& row);
100     };
101
102     bool fdIsValid(const int fd) const;
103     void initTimer();
104     void timerUp();
105     int timespec2ms(const timespec& time);
106     timespec* insertTime(timespec& buffertime);
107     static bool compareCountdown(const sh_timer_s& a, const sh_timer_s& b)
108     {
109         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);
110     }
111
112     static bool onlyFiredEvents(const pollfd& a)
113     {
114         return a.revents == 0 ? false : true;
115     }
116
117     //todo: maybe we could simplify mListActiveTimer to hold only the handle and the countdown ....
118     mListPollfd_t mfdPollingArray;
119     mListPoll_t mListPoll;
120     std::list<sh_timer_s> mListTimer; //!<list of all timers
121     std::list<sh_timer_s> mListActiveTimer; //!<list of all currently active timers
122     sh_timerHandle_t mNextTimer;
123     sh_timerHandle_t mLastInsertedHandle;
124     sh_pollHandle_t mLastInsertedPollHandle;
125     bool mRecreatePollfds;
126     timespec mTimeout;
127 };
128
129 /**
130  * classic functor for the BasicTimerCallback
131  */
132 class CAmShTimerCallBack
133 {
134 public:
135     virtual void Call(const sh_timerHandle_t handle, void* userData)=0;
136     virtual ~CAmShTimerCallBack(){};
137 };
138
139 class CAmShPollPrepare
140 {
141 public:
142     virtual void Call(const sh_pollHandle_t handle, void* userData)=0;
143     virtual ~CAmShPollPrepare(){};
144 };
145
146 class CAmShPollFired
147 {
148 public:
149     virtual void Call(const pollfd pollfd, const sh_pollHandle_t handle, void* userData)=0;
150     virtual ~ CAmShPollFired(){};
151 };
152
153 class CAmShPollCheck
154 {
155 public:
156     virtual bool Call(const sh_pollHandle_t handle, void* userData)=0;
157     virtual ~ CAmShPollCheck(){};
158 };
159
160 class CAmShPollDispatch
161 {
162 public:
163     virtual bool Call(const sh_pollHandle_t handle, void* userData)=0;
164     virtual ~ CAmShPollDispatch() {};
165 };
166
167 /**
168  * template to create the functor for a class
169  */
170 template<class TClass> class TAmShTimerCallBack: public CAmShTimerCallBack
171 {
172 private:
173     TClass* mInstance;
174     void (TClass::*mFunction)(sh_timerHandle_t handle, void* userData);
175
176 public:
177     TAmShTimerCallBack(TClass* instance, void(TClass::*function)(sh_timerHandle_t handle, void* userData)) :
178             mInstance(instance),//
179             mFunction(function) {};
180
181     virtual void Call(sh_timerHandle_t handle, void* userData)
182     {
183         (*mInstance.*mFunction)(handle, userData);
184     }
185 };
186
187 /**
188  * template to create the functor for a class
189  */
190 template<class TClass> class TAmShPollPrepare: public CAmShPollPrepare
191 {
192 private:
193     TClass* mInstance;
194     void (TClass::*mFunction)(const sh_timerHandle_t handle, void* userData);
195
196 public:
197     TAmShPollPrepare(TClass* instance, void(TClass::*function)(const sh_timerHandle_t handle, void* userData)) :
198             mInstance(instance), //
199             mFunction(function){};
200
201     virtual void Call(const sh_timerHandle_t handle, void* userData)
202     {
203         (*mInstance.*mFunction)(handle, userData);
204     };
205 };
206
207 template<class TClass> class TAmShPollFired: public CAmShPollFired
208 {
209 private:
210     TClass* mInstance;
211     void (TClass::*mFunction)(const pollfd pollfd, const sh_pollHandle_t handle, void* userData);
212
213 public:
214     TAmShPollFired(TClass* instance, void(TClass::*function)(const pollfd pollfd, const sh_pollHandle_t handle, void* userData)) :
215             mInstance(instance), //
216             mFunction(function){};
217
218     virtual void Call(const pollfd pollfd, const sh_pollHandle_t handle, void* userData)
219     {
220         (*mInstance.*mFunction)(pollfd, handle, userData);
221     };
222 };
223
224 template<class TClass> class TAmShPollCheck: public CAmShPollCheck
225 {
226 private:
227     TClass* mInstance;
228     bool (TClass::*mFunction)(const sh_pollHandle_t handle, void* userData);
229
230 public:
231     TAmShPollCheck(TClass* instance, bool(TClass::*function)(const sh_pollHandle_t handle, void* userData)) :
232             mInstance(instance), //
233             mFunction(function){};
234
235     virtual bool Call(const sh_pollHandle_t handle, void* userData)
236     {
237         return (*mInstance.*mFunction)(handle, userData);
238     };
239 };
240
241 template<class TClass> class TAmShPollDispatch: public CAmShPollDispatch
242 {
243 private:
244     TClass* mInstance;
245     bool (TClass::*mFunction)(const sh_pollHandle_t handle, void* userData);
246
247 public:
248     TAmShPollDispatch(TClass* instance, bool(TClass::*function)(const sh_pollHandle_t handle, void* userData)) :
249             mInstance(instance), //
250             mFunction(function) {};
251
252     virtual bool Call(const sh_pollHandle_t handle, void* userData)
253     {
254         return (*mInstance.*mFunction)(handle, userData);
255     };
256 };
257 } /* namespace am */
258 #endif /* SOCKETHANDLER_H_ */