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 
62  TaskTime m_ttExpires {};
63  TaskTime m_ttLastNotified {};
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;
99  TaskTime m_ttLastChanged {};
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  explicit 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 */*unused*/) { return (T)(0); }
167 template<>
168 inline QString state_var_init(const QString */*unused*/) { 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  for (const auto *it : qAsConst(m_map))
185  delete it;
186  m_map.clear();
187  }
188 
189  // ------------------------------------------------------------------
190 
192  {
193  if (pBase != nullptr)
194  m_map.insert(pBase->m_sName, pBase);
195  }
196 
197  // ------------------------------------------------------------------
198  template < class T >
199  bool SetValue( const QString &sName, T value )
200  {
201  SVMap::iterator it = m_map.find(sName);
202  if (it == m_map.end())
203  return false;
204 
205  auto *pVariable = dynamic_cast< StateVariable< T > *>( *it );
206 
207  if (pVariable == nullptr)
208  return false; // It's not the expected type.
209 
210  if ( pVariable->GetValue() != value)
211  {
212  pVariable->SetValue( value );
213 
214  if (pVariable->m_bNotify)
215  Notify();
216  }
217 
218  return true;
219  }
220 
221  // ------------------------------------------------------------------
222 
223  template < class T >
224  T GetValue( const QString &sName )
225  {
226  T *dummy = nullptr;
227  SVMap::iterator it = m_map.find(sName);
228  if (it == m_map.end())
229  return state_var_init(dummy);
230 
231  auto *pVariable = dynamic_cast< StateVariable< T > *>( *it );
232 
233  if (pVariable != nullptr)
234  return pVariable->GetValue();
235 
236  return state_var_init(dummy);
237  }
238 
239  uint BuildNotifyBody(QTextStream &ts, TaskTime ttLastNotified) const;
240 };
241 
244 //
245 // Eventing Class Definition
246 //
249 
251  public StateVariables,
252  public IPostProcess,
253  public UPnpServiceImpl
254 {
255 
256  protected:
257 
258  QMutex m_mutex;
259 
262 
263  int m_nSubscriptionDuration {1800};
264 
265  short m_nHoldCount {0};
266 
267  SubscriberInfo *m_pInitializeSubscriber {nullptr};
268 
269  protected:
270 
271  void Notify ( ) override; // StateVariables
272  void NotifySubscriber ( SubscriberInfo *pInfo );
273  void HandleSubscribe ( HTTPRequest *pRequest );
274  void HandleUnsubscribe( HTTPRequest *pRequest );
275 
276  // Implement UPnpServiceImpl methods that we can
277 
278  QString GetServiceEventURL() override // UPnpServiceImpl
279  { return m_sEventMethodName; }
280 
281  public:
282  Eventing ( const QString &sExtensionName,
283  QString sEventMethodName,
284  const QString &sSharePath );
285  ~Eventing ( ) override;
286 
287  QStringList GetBasePaths() override; // HttpServerExtension
288 
289  bool ProcessRequest( HTTPRequest *pRequest ) override; // HttpServerExtension
290 
291  short HoldEvents ( );
292  short ReleaseEvents ( );
293 
294  void ExecutePostProcess( ) override; // IPostProcess
295 
296 
297 };
298 
299 #endif
SubscriberInfo::SubscriberInfo
SubscriberInfo()
Definition: eventing.h:33
StateVariables::Notify
virtual void Notify()=0
state_var_init
T state_var_init(const T *)
Definition: eventing.h:166
HTTPRequest
Definition: httprequest.h:108
Eventing::m_subscribers
Subscribers m_subscribers
Definition: eventing.h:261
Eventing::m_sEventMethodName
QString m_sEventMethodName
Definition: eventing.h:260
StateVariables::m_map
SVMap m_map
Definition: eventing.h:176
StateVariable::GetValue
T GetValue()
Definition: eventing.h:146
Eventing
Definition: eventing.h:254
StateVariable
Definition: eventing.h:118
TaskTime
struct timeval TaskTime
Definition: httpserver.h:45
StateVariable::ToString
QString ToString() override
Definition: eventing.h:139
StateVariableBase::m_bNotify
bool m_bNotify
Definition: eventing.h:97
StateVariable::StateVariable
StateVariable(const QString &sName, bool bNotify=false)
Definition: eventing.h:127
SubscriberInfo
Definition: eventing.h:31
Subscribers
QMap< QString, SubscriberInfo * > Subscribers
Definition: eventing.h:87
SubscriberInfo::m_sUUID
QString m_sUUID
Definition: eventing.h:65
IPostProcess::ExecutePostProcess
virtual void ExecutePostProcess()=0
StateVariables::SVMap
QMap< QString, StateVariableBase * > SVMap
Definition: eventing.h:175
SubscriberInfo::IncrementKey
unsigned long IncrementKey()
Definition: eventing.h:53
StateVariables::SetValue
bool SetValue(const QString &sName, T value)
Definition: eventing.h:199
uint
unsigned int uint
Definition: compat.h:141
SubscriberInfo::m_qURL
QUrl m_qURL
Definition: eventing.h:66
HttpServerExtension::ProcessRequest
virtual bool ProcessRequest(HTTPRequest *pRequest)=0
IPostProcess
Definition: httprequest.h:97
StateVariableBase::StateVariableBase
StateVariableBase(const QString &sName, bool bNotify=false)
Definition: eventing.h:103
SubscriberInfo::SetExpireTime
void SetExpireTime(unsigned long nSecs)
Definition: eventing.h:72
StateVariableBase::~StateVariableBase
virtual ~StateVariableBase()=default
AddMicroSecToTaskTime
void AddMicroSecToTaskTime(TaskTime &t, suseconds_t uSecs)
Definition: upnputil.cpp:107
Eventing::m_mutex
QMutex m_mutex
Definition: eventing.h:258
Eventing::GetServiceEventURL
QString GetServiceEventURL() override
Provides the URL of the event portion of the service.
Definition: eventing.h:278
HttpServerExtension::GetBasePaths
virtual QStringList GetBasePaths()=0
StateVariable::m_value
T m_value
Definition: eventing.h:121
StateVariables::StateVariables
StateVariables()=default
StateVariable::SetValue
void SetValue(T value)
Definition: eventing.h:153
StateVariables::AddVariable
void AddVariable(StateVariableBase *pBase)
Definition: eventing.h:191
UPNP_PUBLIC
#define UPNP_PUBLIC
Definition: upnpexp.h:9
StateVariables::~StateVariables
virtual ~StateVariables()
Definition: eventing.h:182
httpserver.h
upnpserviceimpl.h
HttpServerExtension
Definition: httpserver.h:72
upnputil.h
StateVariables
Definition: eventing.h:171
SubscriberInfo::SubscriberInfo
SubscriberInfo(const QString &url, unsigned long duration)
Definition: eventing.h:41
StateVariables::GetValue
T GetValue(const QString &sName)
Definition: eventing.h:224
StateVariableBase::ToString
virtual QString ToString()=0
StateVariableBase::m_sName
QString m_sName
Definition: eventing.h:98
UPnpServiceImpl
Base class for services we offer to other UPnP devices.
Definition: upnpserviceimpl.h:30
StateVariable::StateVariable
StateVariable(const QString &sName, T value, bool bNotify=false)
Definition: eventing.h:133
StateVariableBase
Definition: eventing.h:94