AudioManager  7.6.6
Native Application Runtime Environment
CAmSocketHandler.h
Go to the documentation of this file.
1 
18 #ifndef SOCKETHANDLER_H_
19 #define SOCKETHANDLER_H_
20 
21 #include <sys/socket.h>
22 #include <stdint.h>
23 #include <sys/poll.h>
24 #include <list>
25 #include <map>
26 #include <set>
27 #include <signal.h>
28 #include <vector>
29 #include <functional>
30 #include <sys/signalfd.h>
31 #include <audiomanagerconfig.h>
32 #include "audiomanagertypes.h"
33 
34 #ifdef WITH_TIMERFD
35 
36 #include <stdio.h>
37 #include <string>
38 #include <stdexcept>
39 #include <unistd.h>
40 #include <fcntl.h>
41 
42 #endif
43 
44 namespace am
45 {
46 
47 #define MAX_NS 1000000000L
48 #define MAX_TIMERHANDLE UINT16_MAX
49 #define MAX_POLLHANDLE UINT16_MAX
50 
51 typedef uint16_t sh_pollHandle_t;
52 typedef sh_pollHandle_t sh_timerHandle_t;
53 
58 {
59 public:
60  virtual void Call(const sh_pollHandle_t handle, void* userData) = 0;
61  virtual ~IAmShPollPrepare() {}
62 };
63 
68 {
69 public:
70  virtual void Call(const pollfd pollfd, const sh_pollHandle_t handle, void* userData) = 0;
71  virtual ~ IAmShPollFired() {}
72 };
73 
78 {
79 public:
80  virtual bool Call(const sh_pollHandle_t handle, void* userData) = 0;
81  virtual ~ IAmShPollCheck() {}
82 };
83 
88 {
89 public:
90  virtual bool Call(const sh_pollHandle_t handle, void* userData) = 0;
91  virtual ~ IAmShPollDispatch() {}
92 };
93 
98 {
99 public:
101  virtual void Call(const sh_timerHandle_t handle, void* userData) = 0;
103 };
104 
108 template<class TClass> class TAmShPollFired: public IAmShPollFired
109 {
110 private:
111  TClass* mInstance;
112  void (TClass::*mFunction)(const pollfd pollfd, const sh_pollHandle_t handle, void* userData);
113 
114 public:
115  TAmShPollFired(TClass* instance, void (TClass::*function)(const pollfd pollfd, const sh_pollHandle_t handle, void* userData)) :
116  mInstance(instance), //
117  mFunction(function)
118  {}
119 
120  virtual void Call(const pollfd pollfd, const sh_pollHandle_t handle, void* userData)
121  {
122  (*mInstance.*mFunction)(pollfd, handle, userData);
123  }
124 };
125 
129 template<class TClass> class TAmShPollCheck: public IAmShPollCheck
130 {
131 private:
132  TClass* mInstance;
133  bool (TClass::*mFunction)(const sh_pollHandle_t handle, void* userData);
134 
135 public:
136  TAmShPollCheck(TClass* instance, bool (TClass::*function)(const sh_pollHandle_t handle, void* userData)) :
137  mInstance(instance), //
138  mFunction(function)
139  {}
140 
141  virtual bool Call(const sh_pollHandle_t handle, void* userData)
142  {
143  return ((*mInstance.*mFunction)(handle, userData));
144  }
145 };
146 
150 template<class TClass> class TAmShPollDispatch: public IAmShPollDispatch
151 {
152 private:
153  TClass* mInstance;
154  bool (TClass::*mFunction)(const sh_pollHandle_t handle, void* userData);
155 
156 public:
157  TAmShPollDispatch(TClass* instance, bool (TClass::*function)(const sh_pollHandle_t handle, void* userData)) :
158  mInstance(instance), //
159  mFunction(function)
160  {}
161 
162  virtual bool Call(const sh_pollHandle_t handle, void* userData)
163  {
164  return ((*mInstance.*mFunction)(handle, userData));
165  }
166 };
167 
171 template<class TClass> class TAmShTimerCallBack: public IAmShTimerCallBack
172 {
173 private:
174  TClass* mInstance;
175  void (TClass::*mFunction)(sh_timerHandle_t handle, void* userData);
176 
177 public:
178  TAmShTimerCallBack(TClass* instance, void (TClass::*function)(sh_timerHandle_t handle, void* userData)) :
179  IAmShTimerCallBack(), mInstance(instance), //
180  mFunction(function)
181  {}
182 
183  virtual void Call(sh_timerHandle_t handle, void* userData)
184  {
185  (*mInstance.*mFunction)(handle, userData);
186  }
187 };
188 
193 template<class TClass> class TAmShPollPrepare: public IAmShPollPrepare
194 {
195 private:
196  TClass* mInstance;
197  void (TClass::*mFunction)(const sh_pollHandle_t handle, void* userData);
198 
199 public:
200  TAmShPollPrepare(TClass* instance, void (TClass::*function)(const sh_pollHandle_t handle, void* userData)) :
201  mInstance(instance), //
202  mFunction(function)
203  {}
204 
205  virtual void Call(const sh_pollHandle_t handle, void* userData)
206  {
207  (*mInstance.*mFunction)(handle, userData);
208  }
209 };
210 
217 {
218  struct sh_poll_s
219  {
220  sh_pollHandle_t handle;
221  pollfd pollfdValue;
222  std::function<void(const sh_pollHandle_t handle, void* userData)> prepareCB; //preperation callback
223  std::function<void(const pollfd pollfd, const sh_pollHandle_t handle, void* userData)> firedCB; //fired callback
224  std::function<bool(const sh_pollHandle_t handle, void* userData)> checkCB; //check callback
225  std::function<bool(const sh_pollHandle_t handle, void* userData)> dispatchCB; //dispatch callback
226  void* userData;
227 
228  sh_poll_s() :
229  handle(0), pollfdValue(), prepareCB(), firedCB(), checkCB(), dispatchCB(), userData(0)
230  {}
231  };
232 
233  struct sh_timer_s
234  {
235  sh_timerHandle_t handle;
236 #ifdef WITH_TIMERFD
237  int fd;
238  itimerspec countdown;
239 #else
240  timespec countdown;
241 #endif
242  std::function<void(const sh_timerHandle_t handle, void* userData)> callback; //timer callback
243  void* userData;
244  sh_timer_s() :
245  handle(0)
246 #ifdef WITH_TIMERFD
247  , fd(0)
248 #endif
249  , countdown(), callback(), userData(0)
250  {}
251  };
252 
253  struct sh_signal_s
254  {
255  sh_pollHandle_t handle;
256  std::function<void(const sh_pollHandle_t handle, const signalfd_siginfo & info, void* userData)> callback;
257  void* userData;
258  sh_signal_s() :
259  handle(0), callback(), userData(0)
260  {}
261  };
262 
263  struct sh_identifier_s
264  {
265  std::set<sh_pollHandle_t> pollHandles;
266  uint16_t limit;
267  uint16_t lastUsedID;
268  sh_identifier_s(const uint16_t pollLimit = UINT16_MAX) :
269  pollHandles(), limit(pollLimit), lastUsedID(0)
270  {}
271  };
272 
273  typedef std::reverse_iterator<sh_timer_s> rListTimerIter;
274  typedef std::vector<pollfd> VectorListPollfd_t;
275  typedef std::vector<sh_poll_s> VectorListPoll_t;
276  typedef std::vector<sh_signal_s> VectorSignalHandlers_t;
277 
278  typedef enum:uint8_t
279  {
280  NO_ERROR = 0u, // OK
281  PIPE_ERROR = 1u, // Pipe error
282  FD_ERROR = 2u, // Invalid file descriptor
283  SFD_ERROR = 4u,
284  } internal_codes_e;
285  typedef uint8_t internal_codes_t;
286 
287  int mPipe[2];
288  bool mDispatchDone; //this starts / stops the mainloop
289 
290  sh_identifier_s mSetPollKeys;
291  VectorListPoll_t mListPoll;
292  sh_identifier_s mSetTimerKeys;
293  std::list<sh_timer_s> mListTimer;
294  std::list<sh_timer_s> mListActiveTimer;
295  sh_identifier_s mSetSignalhandlerKeys;
296  VectorSignalHandlers_t mSignalHandlers;
297  bool mRecreatePollfds;
298  internal_codes_t mInternalCodes;
299  sh_pollHandle_t mSignalFdHandle;
300 #ifndef WITH_TIMERFD
301  timespec mStartTime;
302 #endif
303 private:
304  bool fdIsValid(const int fd) const;
305 
306  timespec* insertTime(timespec& buffertime);
307 #ifdef WITH_TIMERFD
308  am_Error_e createTimeFD(const itimerspec & timeouts, int & fd);
309 
310 #else
311  void timerUp();
312  void timerCorrection();
313 
320  inline static bool compareCountdown(const sh_timer_s& a, const sh_timer_s& b)
321  {
322  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));
323  }
324 
331  inline static timespec timespecSub(const timespec& a, const timespec& b)
332  {
333  timespec result;
334 
335  if ((a.tv_sec < b.tv_sec) || ((a.tv_sec == b.tv_sec) && (a.tv_nsec <= b.tv_nsec)))
336  {
337  result.tv_sec = result.tv_nsec = 0;
338  }
339  else
340  {
341  result.tv_sec = a.tv_sec - b.tv_sec;
342  if (a.tv_nsec < b.tv_nsec)
343  {
344  result.tv_nsec = a.tv_nsec + MAX_NS - b.tv_nsec;
345  result.tv_sec--; /* Borrow a second. */
346  }
347  else
348  {
349  result.tv_nsec = a.tv_nsec - b.tv_nsec;
350  }
351  }
352  return (result);
353  }
354 
361  inline timespec timespecAdd(const timespec& a, const timespec& b)
362  {
363  timespec result;
364  result.tv_sec = a.tv_sec + b.tv_sec;
365  result.tv_nsec = a.tv_nsec + b.tv_nsec;
366  if (result.tv_nsec >= MAX_NS)
367  {
368  result.tv_sec++;
369  result.tv_nsec = result.tv_nsec - MAX_NS;
370  }
371  return (result);
372  }
373 
380  inline int timespecCompare(const timespec& a, const timespec& b)
381  {
382  //less
383  if (a.tv_sec < b.tv_sec)
384  return (-1);
385  //greater
386  else if (a.tv_sec > b.tv_sec)
387  return (1);
388  //less
389  else if (a.tv_nsec < b.tv_nsec)
390  return (-1);
391  //greater
392  else if (a.tv_nsec > b.tv_nsec)
393  return (1);
394  //equal
395  return (0);
396  }
397 #endif
398 
404  inline static void prepare(sh_poll_s& row);
405 
411  inline static void fire(sh_poll_s& a);
412 
418  inline static bool eventFired(const pollfd& a);
419 
425  inline static bool noDispatching(const sh_poll_s& a);
426 
432  inline static bool dispatchingFinished(const sh_poll_s& a);
433 
439  inline static void callTimer(sh_timer_s& a);
440 
446  bool nextHandle(sh_identifier_s & handle);
447 
448  am_Error_e getFDPollData(const sh_pollHandle_t handle, sh_poll_s & outPollData);
449 
450 public:
451 
453  ~CAmSocketHandler();
454 
458  am_Error_e listenToSignals(const std::vector<uint8_t> & listSignals);
459 
460  am_Error_e addFDPoll(const int fd, const short event, std::function<void(const sh_pollHandle_t handle, void* userData)> prepare, std::function<void(const pollfd pollfd, const sh_pollHandle_t handle, void* userData)> fired,
461  std::function<bool(const sh_pollHandle_t handle, void* userData)> check, std::function<bool(const sh_pollHandle_t handle, void* userData)> dispatch, void* userData, sh_pollHandle_t& handle);
462 
463  am_Error_e addFDPoll(const int fd, const short event, IAmShPollPrepare *prepare, IAmShPollFired *fired, IAmShPollCheck *check, IAmShPollDispatch *dispatch, void* userData, sh_pollHandle_t& handle);
464  am_Error_e removeFDPoll(const sh_pollHandle_t handle);
465  am_Error_e updateEventFlags(const sh_pollHandle_t handle, const short events);
466  am_Error_e addSignalHandler(std::function<void(const sh_pollHandle_t handle, const signalfd_siginfo & info, void* userData)> callback, sh_pollHandle_t& handle, void * userData);
467  am_Error_e removeSignalHandler(const sh_pollHandle_t handle);
468  am_Error_e addTimer(const timespec & timeouts, IAmShTimerCallBack* callback, sh_timerHandle_t& handle, void * userData,
469 #ifndef WITH_TIMERFD
470  const bool __attribute__((__unused__)) repeats = false
471 #else
472  const bool repeats = false
473 #endif
474  );
475  am_Error_e addTimer(const timespec & timeouts, std::function<void(const sh_timerHandle_t handle, void* userData)> callback, sh_timerHandle_t& handle, void* userData,
476 #ifndef WITH_TIMERFD
477  const bool __attribute__((__unused__)) repeats = false
478 #else
479  const bool repeats = false
480 #endif
481  );
482  am_Error_e removeTimer(const sh_timerHandle_t handle);
483  am_Error_e restartTimer(const sh_timerHandle_t handle);
484  am_Error_e updateTimer(const sh_timerHandle_t handle, const timespec & timeouts);
485  am_Error_e stopTimer(const sh_timerHandle_t handle);
486  void start_listenting();
487  void stop_listening();
488  void exit_mainloop();
489 
490  bool fatalErrorOccurred();
491 };
492 
493 } /* namespace am */
494 #endif /* SOCKETHANDLER_H_ */
A Common-API wrapper class, which loads the common-api runtime and instantiates all necessary objects...
am_Error_e
the errors of the audiomanager.
virtual void Call(sh_timerHandle_t handle, void *userData)
template for a callback
prototype for poll fired callback
make private, not public template for a callback
virtual void Call(const sh_pollHandle_t handle, void *userData)
The am::CAmSocketHandler implements a mainloop for the AudioManager.
uint16_t sh_pollHandle_t
this is a handle for a filedescriptor to be used with the SocketHandler
prototype for poll check callback
prototype for poll prepared callback
TAmShPollDispatch(TClass *instance, bool(TClass::*function)(const sh_pollHandle_t handle, void *userData))
virtual bool Call(const sh_pollHandle_t handle, void *userData)
virtual void Call(const sh_pollHandle_t handle, void *userData)=0
template for a callback
template for a callback
TAmShPollFired(TClass *instance, void(TClass::*function)(const pollfd pollfd, const sh_pollHandle_t handle, void *userData))
prototype for dispatch callback
virtual bool Call(const sh_pollHandle_t handle, void *userData)
virtual void Call(const pollfd pollfd, const sh_pollHandle_t handle, void *userData)
Copyright (C) 2012 - 2014, BMW AG.
TAmShTimerCallBack(TClass *instance, void(TClass::*function)(sh_timerHandle_t handle, void *userData))
TAmShPollCheck(TClass *instance, bool(TClass::*function)(const sh_pollHandle_t handle, void *userData))
prototype for the timer callback
#define MAX_NS
TAmShPollPrepare(TClass *instance, void(TClass::*function)(const sh_pollHandle_t handle, void *userData))
sh_pollHandle_t sh_timerHandle_t
this is a handle for a timer to be used with the SocketHandler
template to create the functor for a class