MythTV  master
eventing.h
Go to the documentation of this file.
1 // Program Name: Eventing.h
3 // Created : Dec. 22, 2006
4 //
5 // Purpose : uPnp Eventing Base Class Definition
6 //
7 // Copyright (c) 2006 David Blain <dblain@mythtv.org>
8 //
9 // Licensed under the GPL v2 or later, see COPYING for details
10 //
12 
13 #ifndef EVENTING_H_
14 #define EVENTING_H_
15 
16 #include <QUrl>
17 #include <QUuid>
18 #include <QMap>
19 
20 #include "upnpserviceimpl.h"
21 #include "upnputil.h"
22 #include "httpserver.h"
23 
24 class QTextStream;
25 
27 //
29 
31 {
32  public:
34  {
35  memset( &m_ttExpires, 0, sizeof( m_ttExpires ) );
36  memset( &m_ttLastNotified, 0, sizeof( m_ttLastNotified ) );
37  m_sUUID = QUuid::createUuid().toString();
38  m_sUUID = m_sUUID.mid( 1, m_sUUID.length() - 2);
39  }
40 
41  SubscriberInfo( const QString &url, unsigned long duration )
42  : m_nDuration( duration )
43  {
44  memset( &m_ttExpires, 0, sizeof( m_ttExpires ) );
45  memset( &m_ttLastNotified, 0, sizeof( m_ttLastNotified ) );
46  m_sUUID = QUuid::createUuid().toString();
47  m_sUUID = m_sUUID.mid( 1, m_sUUID.length() - 2);
48  m_qURL = url;
49 
50  SetExpireTime( m_nDuration );
51  }
52 
53  unsigned long IncrementKey()
54  {
55  // When key wraps around to zero again... must make it a 1. (upnp spec)
56  if ((++m_nKey) == 0)
57  m_nKey = 1;
58 
59  return m_nKey;
60  }
61 
64 
65  QString m_sUUID;
66  QUrl m_qURL;
67  unsigned short m_nKey {0};
68  unsigned long m_nDuration {0}; // Seconds
69 
70  protected:
71 
72  void SetExpireTime( unsigned long nSecs )
73  {
74  TaskTime tt;
75  gettimeofday( (&tt), nullptr );
76 
77  AddMicroSecToTaskTime( tt, (nSecs * 1000000) );
78 
79  m_ttExpires = tt;
80  }
81 
82 
83 };
84 
86 
87 using Subscribers = QMap<QString,SubscriberInfo*>;
88 
90 //
92 
94 {
95  public:
96 
97  bool m_bNotify;
98  QString m_sName;
100 
101  public:
102 
103  explicit StateVariableBase( const QString &sName, bool bNotify = false )
104  {
105  m_bNotify = bNotify;
106  m_sName = sName;
107  gettimeofday( (&m_ttLastChanged), nullptr );
108  }
109  virtual ~StateVariableBase() = default;
110 
111  virtual QString ToString() = 0;
112 };
113 
115 
116 template< class T >
118 {
119  private:
120 
122 
123  public:
124 
125  // ------------------------------------------------------------------
126 
127  StateVariable( const QString &sName, bool bNotify = false ) : StateVariableBase( sName, bNotify ), m_value( T( ) )
128  {
129  }
130 
131  // ------------------------------------------------------------------
132 
133  StateVariable( const QString &sName, T value, bool bNotify = false ) : StateVariableBase( sName, bNotify ), m_value(value)
134  {
135  }
136 
137  // ------------------------------------------------------------------
138 
139  QString ToString() override // StateVariableBase
140  {
141  return QString( "%1" ).arg( m_value );
142  }
143 
144  // ------------------------------------------------------------------
145 
147  {
148  return m_value;
149  }
150 
151  // ------------------------------------------------------------------
152 
153  void SetValue( T value )
154  {
155  if ( m_value != value )
156  {
157  m_value = value;
158  gettimeofday( (&m_ttLastChanged), nullptr );
159  }
160  }
161 };
162 
164 
165 template<typename T>
166 inline T state_var_init(const T*) { return (T)(0); }
167 template<>
168 inline QString state_var_init(const QString*) { return QString(); }
169 
171 {
172  protected:
173 
174  virtual void Notify() = 0;
175  using SVMap = QMap<QString, StateVariableBase*>;
177  public:
178 
179  // ------------------------------------------------------------------
180 
181  StateVariables() = default;
182  virtual ~StateVariables()
183  {
184  SVMap::iterator it = m_map.begin();
185  for (; it != m_map.end(); ++it)
186  delete *it;
187  m_map.clear();
188  }
189 
190  // ------------------------------------------------------------------
191 
193  {
194  if (pBase != nullptr)
195  m_map.insert(pBase->m_sName, pBase);
196  }
197 
198  // ------------------------------------------------------------------
199  template < class T >
200  bool SetValue( const QString &sName, T value )
201  {
202  SVMap::iterator it = m_map.find(sName);
203  if (it == m_map.end())
204  return false;
205 
206  StateVariable< T > *pVariable =
207  dynamic_cast< StateVariable< T > *>( *it );
208 
209  if (pVariable == nullptr)
210  return false; // It's not the expected type.
211 
212  if ( pVariable->GetValue() != value)
213  {
214  pVariable->SetValue( value );
215 
216  if (pVariable->m_bNotify)
217  Notify();
218  }
219 
220  return true;
221  }
222 
223  // ------------------------------------------------------------------
224 
225  template < class T >
226  T GetValue( const QString &sName )
227  {
228  T *dummy = nullptr;
229  SVMap::iterator it = m_map.find(sName);
230  if (it == m_map.end())
231  return state_var_init(dummy);
232 
233  StateVariable< T > *pVariable =
234  dynamic_cast< StateVariable< T > *>( *it );
235 
236  if (pVariable != nullptr)
237  return pVariable->GetValue();
238 
239  return state_var_init(dummy);
240  }
241 
242  uint BuildNotifyBody(QTextStream &ts, TaskTime ttLastNotified) const;
243 };
244 
247 //
248 // Eventing Class Definition
249 //
252 
254  public StateVariables,
255  public IPostProcess,
256  public UPnpServiceImpl
257 {
258 
259  protected:
260 
261  QMutex m_mutex;
262 
265 
266  int m_nSubscriptionDuration {1800};
267 
268  short m_nHoldCount {0};
269 
270  SubscriberInfo *m_pInitializeSubscriber {nullptr};
271 
272  protected:
273 
274  void Notify ( ) override; // StateVariables
275  void NotifySubscriber ( SubscriberInfo *pInfo );
276  void HandleSubscribe ( HTTPRequest *pRequest );
277  void HandleUnsubscribe( HTTPRequest *pRequest );
278 
279  // Implement UPnpServiceImpl methods that we can
280 
281  QString GetServiceEventURL() override // UPnpServiceImpl
282  { return m_sEventMethodName; }
283 
284  public:
285  Eventing ( const QString &sExtensionName,
286  QString sEventMethodName,
287  const QString &sSharePath );
288  virtual ~Eventing ( );
289 
290  QStringList GetBasePaths() override; // HttpServerExtension
291 
292  bool ProcessRequest( HTTPRequest *pRequest ) override; // HttpServerExtension
293 
294  short HoldEvents ( );
295  short ReleaseEvents ( );
296 
297  void ExecutePostProcess( ) override; // IPostProcess
298 
299 
300 };
301 
302 #endif
Base class for services we offer to other UPnP devices.
QString m_sName
Definition: eventing.h:98
QMutex m_mutex
Definition: eventing.h:261
T state_var_init(const T *)
Definition: eventing.h:166
struct timeval TaskTime
Definition: httpserver.h:45
unsigned long IncrementKey()
Definition: eventing.h:53
void AddMicroSecToTaskTime(TaskTime &t, suseconds_t uSecs)
Definition: upnputil.cpp:103
void SetValue(T value)
Definition: eventing.h:153
void SetExpireTime(unsigned long nSecs)
Definition: eventing.h:72
QString GetServiceEventURL() override
Provides the URL of the event portion of the service.
Definition: eventing.h:281
virtual bool ProcessRequest(HTTPRequest *pRequest)=0
StateVariable(const QString &sName, T value, bool bNotify=false)
Definition: eventing.h:133
TaskTime m_ttExpires
Definition: eventing.h:62
StateVariable(const QString &sName, bool bNotify=false)
Definition: eventing.h:127
QMap< QString, StateVariableBase * > SVMap
Definition: eventing.h:175
TaskTime m_ttLastChanged
Definition: eventing.h:99
QString ToString() override
Definition: eventing.h:139
unsigned int uint
Definition: compat.h:140
#define UPNP_PUBLIC
Definition: upnpexp.h:9
StateVariableBase(const QString &sName, bool bNotify=false)
Definition: eventing.h:103
TaskTime m_ttLastNotified
Definition: eventing.h:63
bool SetValue(const QString &sName, T value)
Definition: eventing.h:200
QString m_sUUID
Definition: eventing.h:65
SubscriberInfo(const QString &url, unsigned long duration)
Definition: eventing.h:41
virtual void ExecutePostProcess()=0
Subscribers m_Subscribers
Definition: eventing.h:264
virtual QStringList GetBasePaths()=0
void AddVariable(StateVariableBase *pBase)
Definition: eventing.h:192
virtual ~StateVariables()
Definition: eventing.h:182
T GetValue(const QString &sName)
Definition: eventing.h:226
QMap< QString, SubscriberInfo * > Subscribers
Definition: eventing.h:87
QString m_sEventMethodName
Definition: eventing.h:263
virtual void Notify()=0